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

Copying a changing object to inside a block, so the block has the correct value

我有这个循环 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是强引用。我是否需要在调用 dispatch_async 之前创建一个 __weak 版本并在 dispatch_async 中创建一个 __strong 引用以便没有保留周期?

你问:

  1. I suspect every block will hold a reference to its corresponding aDict, so they will not crash even if they execute when the caller is out of scope, right?

它会在块运行时保持强引用,所以你不必担心它会被你释放。

话虽如此,但问题是 fillDictWithCurrentValues 的作用。如果它每次都创建一个新字典,那很好。但是,如果它返回对某些共享字典的引用,这可能会有问题。这仅取决于此方法的作用。

  1. aDict is a strong reference. Do I need to create a __weak version before calling the dispatch_async and a __strong reference inside the dispatch_async so there is no retain cycle?

没有强引用循环,因为当dispatch_async完成运行块时,块将被释放。

如果 (a) self 有可能在闭包完成之前被释放 运行; (b) 您认为关闭不会阻止这种情况的发生很重要。但通常情况下,当将更新分派回主队列时(您只使用非常快的例程执行此操作),您不必担心。