将更改的对象复制到块内,因此块具有正确的值

时间:2016-11-05 04:01:51

标签: objective-c objective-c-blocks

我有这个NSDictionary的循环。每转一圈,这个NSDictionary都是用新值创建的。问题是这个循环触发了一个要执行的异步块。类似的东西:

for (int i=0; i<10; i++) {
  NSDictionary *aDict = [self fillDictWithCurrentValues];
    dispatch_async(dispatch_get_main_queue(), ^{
       executeBlock(aDict);
  });
}

我的问题是这个。我希望这个块在传递给它的字典中执行,但因为循环执行得更快,所以当executeBlock运行时它将超出范围。所以,有两个问题:

  1. 我怀疑每个块都会持有对其aDict的引用,所以即使它们在调用者超出范围时执行它们也不会崩溃,对吗?
  2. aDict是一个很好的参考。在__weak内调用dispatch_async__strong引用之前,是否需要创建dispatch_async版本,以便没有保留周期?

1 个答案:

答案 0 :(得分:2)

你问:

  
      
  1. 我怀疑每个块都会保存对应aDict的引用,所以即使它们在调用者超出范围时执行它们也不会崩溃,对吧?
  2.   

它会在块运行时保持强大的参考,因此您不必担心它会被释放。

有人说过,fillDictWithCurrentValues有什么问题。如果它每次都创建一个新词典,那你就没事了。但是,如果它返回一些共享的字典的引用,这可能会有问题。这取决于这种方法的作用。

  
      
  1. aDict是一个很好的参考。在__weak内调用dispatch_async__strong引用之前,是否需要创建dispatch_async版本,以便没有保留周期?
  2.   

没有强大的参考周期,因为当dispatch_async运行块时,块将被释放。

如果(a)有可能在关闭运行之前释放weakSelf,则您仍可以使用self模式; (b)您认为关闭并不能防止这种情况发生,这一点非常重要。但通常情况下,当将更新发送回主队列(您只使用非常快速的例程)时,您不必担心它。