ios - findObjectsInBackgroundWithBlock : gets data from Parse, 但数据只存在于 block 内

标签 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 时,它运行良好,并且我看到我的整个字典逐渐被填充。但是,在 block 结束后,当我再次打印字典时,它现在是空的。我仔细检查了查询 API 文档,但我仍然不确定我做错了什么。

最佳答案

最后一个 NSLog(@"The dictionary is %@", self.scoreDictionary) 语句在 block 完成后实际上并没有执行。它在 findObjectsInBackgroundWithBlock 方法返回后执行。 findObjectsInBackgroundWithBlock 大概在一个单独的线程中运行某些东西,并且您的 block 可能根本不会真正执行,直到最后一个 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

您可能想考虑,在检索到 scoreDictionary 数据后,您希望对它做什么?例如,是否要更新 UI、调用其他方法等?您将希望在您的 block 执行此操作,此时您知道数据已成功检索。例如,如果您有一个要重新加载的 TableView ,您可以这样做:

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

请注意 dispatch_async - 如果您在更新数据后需要做的工作涉及更改 UI,您会希望它在主线程上运行。

关于ios - findObjectsInBackgroundWithBlock : gets data from Parse, 但数据只存在于 block 内,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18021880/

相关文章:

ios - 不推荐使用UIWebView API,Apple将停止接受使用UIWebView API的应用程序的提交

ios - Pod Install 无权访问私有(private) repo,但 git clone 等在同一个 repo 上工作

objective-c - Clang 和 gcc 选项可以抑制未定义的消息警告?

node.js - JS Lambda 范围与 async.parallel 调用

javascript - 谷歌云存储 (Js)、异步/等待和云功能错误

ios - 如何使用 Swift 4 将数据从 Pop-Over subview 传递到 View Controller

objective-c - SetFrame 适用于 iPhone,但不适用于 iPad。自动调整蒙版大小是罪魁祸首?

objective-c - 自定义 UIView 和 becomeFirstResponder

spring - @Async 会发生什么。是否超时?

iphone - 可以使用 MapKit 在 map 上添加叠加层吗?