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

我做了以下testing类来尝试从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文档,但我仍然不确定我做错了什么。

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

 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 

您可能想要考虑一下, 在检索到scoreDictionary数据后,您想怎么做 ? 例如,你是否想要更新UI,调用其他方法等? 你会想你的区块做到这一点,在这一点上,你知道数据已成功检索。 例如,如果你有一个表视图,你想重新加载,你可以这样做:

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

请注意dispatch_async – 如果更新数据后需要执行的工作涉及更改UI,则需要在主线程上运行。

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

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

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