0

我想更新我的 ViewController 的属性,该属性self.matchedUsers从我通过块异步运行的查询中获取数据。

然后某个地方当我通过 检索计数时[self.matchedUsers count],尽管知道多个对象已添加到我的属性中,但我仍然得到 0。我的问题是,即使我通过块异步检索数据,如何确保我的属性得到更新?谢谢!

更新:

对于上下文,这里是块:

//Way earlier in an initializer:
self.matchedUsers = [[NSMutableArray alloc] init];

//In a method much later
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
   if (!error){
     //Code that updates self.matchedUsers with the NSArray objects
               dispatch_async(dispatch_get_main_queue(), ^{
                    [self.matchedUsers addObjectsFromArray: objects];
                });
     //Question relates to ensure how property could be updated 
   }
 }];
4

2 回答 2

1

正如其他人所写的那样,问题可能是缺少初始化matchedUsers但是......

...问题也可能是由于您的主线程被阻塞。您写道您“稍后在某处检索计数”。如果这与进行第一次调度的方法相同,那么您将遇到麻烦。考虑这段代码

NSMutableArray *collection = [[NSMutableArray alloc] init];
dispatch_async(dispatch_get_global_queue(0, 0), ^{
    NSArray *array = [[NSArray alloc] initWithObjects:@"1", nil];
    dispatch_async(dispatch_get_main_queue(), ^{
        for (NSString *item in array){
            [collection addObject:item];
        }
        NSLog(@"A");
    });
});

[NSThread sleepForTimeInterval:5];
NSLog(@"B");

如果它在主线程上运行,它将先输出 B 然后输出 A(无论睡眠时间),因为该块在方法完成执行之前不会运行。另一方面,如果您分派到另一个全局队列而不是主队列,它将是 A,然后是 B。

于 2013-10-10T20:55:00.297 回答
1

如果您没有忘记初始化matchedUsers,这应该可以工作,您在它被更改后检查它的值并且array在您计划和执行块的时间之间不会丢失它的元素。

但是,我更愿意编写一个可以从任何线程调用的方法,比如

- (void)addUser ...
     @synchronized(self.usersToAdd) {
          [self.usersToAdd addObjectsFromArray: array];
           Enqueue on main thread { 
               NSArray *addingNow;
               @synchronized(self.usersToAdd) {
                   addingNow = [self.usersToAdd copy];
                   [self.usersToAdd removeObjects...
               }
               if (addingNow.count) {
                   [self.users addObjectsFromArray: addingNow;
                   [self.tableView insertRowsWithIndexPaths...
               }
           }
      }
 }
于 2013-10-10T20:41:18.647 回答