findObjectsInBackgroundWithBlock:从Parse获取数据,但数据仅存在于块内

时间:2013-08-02 16:28:23

标签: ios objective-c asynchronous parse-platform

我制作了以下测试类来尝试从Parse中检索数据:

-(void)retrieveDataFromParse
{
    PFQuery *query = [PFQuery queryWithClassName:@"TestObject"];

    [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
        if(!error){
            for (PFObject *object in objects){
                NSString *nameFromObject = [NSString stringWithFormat:@"%@", [object objectForKey:@"Name"]];
                NSString *dateFromObject = [NSString stringWithFormat:@"%@", [object createdAt]];
                NSString *scoreFromObject = [NSString stringWithFormat:@"%@", [object objectForKey:@"Score"]];
                [self addNewScore:scoreFromObject andDate:dateFromObject forUserName:nameFromObject];
                NSLog(@"The dictionary is %@", self.scoreDictionary); //<-- here it works printing out the whole dictionary
            }
        } else {
            NSLog(@"Error: %@ %@", error, [error userInfo]);
        }
    }];
    NSLog(@"The dictionary is %@", self.scoreDictionary); //<- but after the block is called, here the dictionary is again empty...
}

根据代码中的注释部分,当我在代码中打印self.scoreDictionary时,它运行正常,我看到整个字典,因为它逐渐被填充。但是,在块结束后,当我再次打印字典时,它现在是空的。我仔细检查了查询API文档,但我仍然不确定我做错了什么。

2 个答案:

答案 0 :(得分:13)

在块完成后,最后NSLog(@"The dictionary is %@", self.scoreDictionary)语句实际上不会执行。它在findObjectsInBackgroundWithBlock方法返回后执行。 findObjectsInBackgroundWithBlock可能在一个单独的线程中运行某些东西,并且你的块实际上可能根本不会执行,直到最后一个NSLog语句之后的一段时间。从图形上看,这样的事情可能正在发生:

Thread 1 
--------
retriveDataFromParse called
invoke findObjectsInBackgroundWithBlock
findObjectsInBackgroundWithBlock queues up work on another thread
findObjectsInBackgroundWithBlock returns immediately      |
NSLog statement - self.scoreDictionary not yet updated    |
retriveDataFromParse returns                              |
.                                                         V
.                       Thread 2, starting X milliseconds later
.                       --------
.                       findObjectsInBackgroundWithBlock does some work
.                       your block is called
.                       for-loop in your block
.                       Now self.scoreDictionary has some data
.                       NSLog statement inside your block

您可能想要考虑,在您检索得分后,您想对得分数据做什么?例如,您想要更新UI,调用其他方法等吗?您需要在块里面执行此操作,此时您知道数据已成功检索。例如,如果您想要重新加载表视图,则可以执行以下操作:

for (PFObject *object in objects){
    ....
}
dispatch_async(dispatch_get_main_queue(), ^{
    [self updateMyUserInterfaceOrSomething];
});

请注意dispatch_async - 如果您在更新数据后需要做的工作涉及更改用户界面,那么您将希望在主线程上运行。

答案 1 :(得分:0)

在完成块执行之前执行最后一个NSLog(@"The dictionary is %@", self.scoreDictionary)。到那时,self.scoreDictionary肯定是空的。

此外,完成块将在主线程上执行。您可以参考以下链接。

https://parse.com/questions/what-thread-does-findobjectsinbackgroundwithblock-complete-on