解析消息传递应用程序,需要找到一种方法推迟直到deleteAllInBackground完成执行代码的执行。详细的代码包括 - Parse messaging app, need to find a way to delay code execution until deleteAllInBackground finishes executing. Detailed code included

- 此内容更新于:2015-12-13
主题:

有一些问题与我的代码中,我使用解析框架构建一个简单的消息传递系统。我需要推迟直到完成后台进程调用的方法执行。下面的代码。首先我注册界面控制器作为观察者的解析推送通知。当接收到推receivedPush方法调用。然后调用displaymessage推。在messageBankdisplaymessage程序第一次查询。消息银行是一个类,它包含用户名,指向消息类的实例。每条消息放在一个数组作为参数,并显示为UIAlertView(这只是暂时的,出于测试目的)。代码功能应该但有一个很大的问题,如果收到推送通知和receivedMessages然后displaymessage叫做[PFObjectdeleteAllInBackground:删除),在后台运行,所以如果收到消息太快程序将显示重复消息,因为他们尚未完成删除。我需要做的是等待deleteAllInBackground允许displaymessage被称为前完成。我曾经尝试过使用一个nsoperation的队列,但这并没有帮助,因为如果displaymessage在队列,它将被视为完成即使后台删除仍在运行。能让我实现这个愿望呢?只需要displaymessage等到deleteAllInBackground重调之前完成。任何帮助将不胜感激。在圈子里这里!谢谢

原文:

Having some issues with my code, I am building a simple messaging system using the Parse framework. I need to somehow delay the call of a method until a background process is finished executing. Code is below. First I register the UIViewController as an observer for a Parse Push Notification. When a push is received the method receivedPush is called. Received push then calls displayMessages.

 - (void)viewDidLoad {

     [super viewDidLoad];


     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receivedMessage) name:@"receivedPush" object:nil];
}


-(void)receivedMessage
{
   [self displayMessages];

}


-(void)displayMessages
{

    //here I want to cycle through the message objects

    NSMutableArray *toDelete = [[NSMutableArray alloc] init];
    PFQuery *messageBankQuery = [PFQuery queryWithClassName:@"messageBank"];
    [messageBankQuery whereKey:@"username" equalTo:[PFUser currentUser].username];
    [messageBankQuery findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {

        if(!error) {

            PFObject *messageBank = objects[0];
            PFRelation *receivedMessages = [messageBank relationForKey:@"receivedMessages"];
            PFQuery *receivedMessagesQuery = [receivedMessages query];
            [receivedMessagesQuery orderByAscending:@"createdAt"];

            [receivedMessagesQuery findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {

                if((!error) &&([objects count]>0)) {

                    for(PFObject *message in objects) {

                        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Push!" message:miao[@"username"] delegate:self cancelButtonTitle:@"Okay" otherButtonTitles:nil];
                        [alert show];

                        //add to the delete items array
                        [toDelete addObject:message];



                    }



                        if([toDelete count]>0) {
                            //delete all using the array, single API call
                            [PFObject deleteAllInBackground:toDelete];

                        }


                }//end if

            }];//end receivedMessagesQuery

        }

    }];//end messageBankQuery



}

In displayMessages the program first queries the messageBank. The message bank is a class that contains usernames that point to instances of the message class. Each message is put in an array and displayed as a UIAlertView (this is just temporary and for testing purposes).

The code functions as it should but there is a big problem in that if a Push Notification is received and receivedMessages and then displayMessages is called [PFObject deleteAllInBackground:toDelete]; runs in the background so if messages are received too quickly the program will display duplicate messages as they have not yet finished deleting. What I need to do is wait for deleteAllInBackground to finish before allowing displayMessages to be called. I have tried using an NSOperations queue but this doesn't help because if displayMessages is in a queue it will count as finished even if the background delete is still running. Is there anyway I can get around this? Just need displayMessages to wait until deleteAllInBackground to finish before retuning. Any help would be greatly appreciated. Going around in circles here! Thanks

解决方案:
你应该使用你知道当删除完成。你的建议是好的,但是你需要做一些工作来创建一个操作,仍然是“奔跑”到最后所有的异步处理完成。有一些指南,就像这一个。
原文:

You should be using deleteAllInBackground:block: so that you know when the delete is complete.

Your NSOperationQueue suggestion is a good one, but you need to do a little work to create an operation which continues to be 'running' until the end of all of the asynchronous processing is complete. There are a few guides, like this one.

网友:我可以使用deleteAllInBackground:块但如何帮助?我可以如BOOLisDeleting和设置一个标志变量,当块完成执行,但是问题是,因为我使用推送通知receivedMessages可以随时调用,它只是叫一次。所以也许这叫做isDeleting是肯定的。我去哪里吗?只能想到用一个计时器和继续检查,直到该变量被设为NO。但它似乎并不像一个很好的方法。

(原文:I can use deleteAllInBackground:block but how would that help? I could have a flag variable such as BOOL isDeleting and set that to NO when the block finishes execution but the problem is that because I am using Push Notifications receivedMessages can be called at anytime and it is just called once. So perhaps it is called and isDeleting is YES. Where do I go from there? Can only think of using a timer and to keep checking until that variable is set to NO. But it doesn't seem like a nice method.)

楼主:你有想过使用一个运行队列,可以,你只需要执行一次只有一个操作和异步操作的工作。

(原文:You have thought about using an operation queue, and you can, you just need to execute only one operation at a time and to make the operation work asynchronously.)

网友:我试着这NSInvocationOperation*op=[[NSInvocationOperationalloc]initWithTarget:自我选择器:@selector(displaymessage)对象:零),把这段代码是在receivedMessages。所以队列,而不是直接调用它。这个队列调用displaymessage但不是等待deleteAllInBackground完成。displaymessage完成执行即使deleteAllinBackground仍在运行。

(原文:I tried this NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(displayMessages) object:nil] and putting this code was in receivedMessages. So it queues it instead of directly calling it. This queues up calls to displayMessages but it isn't waiting for deleteAllInBackground to finish. displayMessaged finishes executing even if deleteAllinBackground is still running.)

楼主:你读这篇文章我联系了吗?有点过时,但描述您需要遵循的流程与操作。

(原文:Did you read the article I linked to? It is a little out of date but describes the process you need to follow with the operation.)

网友:看看它。如果我创建一个并发操作这_isExecuting_isFinishedvar。这是真的吗?和操作只会完成当_isFinished设置为YES?

(原文:taking a look at it. If I create a concurrent operation this has _isExecuting and _isFinished vars. Is this true? And the operation will only finish when _isFinished is set to YES?)

解决方案:
你应该做的是添加一个boolean字段“显示”消息对象声明是否显示的信息和展示国旗的消息是真实的。然后在你的演示循环,跳过的消息已经显示,在你删除函数删除所有标记的消息。
原文:

What you should do is add a boolean field "Displayed" to the message object stating if the message was shown or not and flag messages that were displayed as true. Then in your presentation loop, skip messages that were already shown and in your delete function delete all the messages that are flagged.

网友:萎靡不振的消息显示或不需要API调用,saveInBackground:块。我会遇到同样的问题,表示循环运行同时saveInBackground可能仍在后台运行修改布尔字段。

(原文:Flagging messages as displayed or not would need API calls though, saveInBackground:block. I would run into the same problem, the presentation loop running whilst saveInBackground is potentially still running in the background modifying the boolean fields.)

网友:如果迟迟不保存更改像我之前方法太慢则会显示重复删除消息。

(原文:if it's too slow to save the changes like my prior method is too slow to delete messages then duplicates will be shown.)

网友:@kek如果问题呈现复制然后你需要做的是不显示的消息已经在你们当地删除数组,然后删除时,你不必等待删除。使它成为一个房地产之类的所以不会重置displaymessage调用之间

(原文:@kek If the problem is presenting duplicates then what you need to do is not display messages that are already in you local toDelete array, and then they are deleted whenever and you don't have to wait for the deletion to end. Make it a property or something so it wont reset between displayMessages calls)

解决方案:
你的问题是同步显示和删除消息。我不明白你写的查询——这是困惑你删除消息displaymessage方法!保持单独显示信息和删除消息并创建它们之间的依赖就像我建议在并发NSOperation和如何设置结束isExecuting吗?你需要重新构建你的解决方案。
原文:

You problem is synchronizing display and delete messages. I don't understand the queries you wrote - it is confusing as you deleting messages in displayMessages method!

Keep display message and delete messages separate and create dependency between them like I have suggested in Concurrent NSOperation and how to set isFinished and isExecuting?

You need to re-architect your solution.