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
- iOS中的NSOperation – 如何处理循环和嵌套的NSOperation调用来获取图像
- 如何使用Swift在iOS上同步运行两个函数
- 在可重用表格单元格中使用NSCache和dispatch_async的正确方法是什么?
- 如何asynchronous加载dynamicUITableView图像?
- 迅速closures和asynchronous任务
- dispatch_async UIWebView的loadrequest
- 如何包装一个asynchronous方法,它将一个块转换为同步的目标c
- sendAsynchronousRequest使UI冻结
- 即使在dispatch_async上,UILabel也不会更新