强烈引用块内的弱引用

luk*_*s_o 9 objective-c ios objective-c-blocks

为什么有必要强烈引用块内的弱引用?

我知道在块内部有一个弱引用将避免保留周期.但为什么必须再次强烈提及弱者呢?

背景:
正如梅森所描述的,这是最佳实践.

我知道在块内引用self的正确方法是在块外创建一个弱引用,然后在块内强引用该弱引用[...]

例:

__weak typeof(self) weakSelf = self;
void (^someBlock)(id) = ^(id data){
    typeof(self) strongSelf = weakSelf;
    // code using strongSelf
});
Run Code Online (Sandbox Code Playgroud)

Chr*_*eux 15

想象一下,对self的最后一个强引用是保存在与你的块运行的线程不同的线程上.

现在这发生了:

__weak typeof(self) weakSelf = self;
void (^someBlock)(id) = ^(id data){
    if (weakSelf != nil) {
       // last remaining strong reference released by another thread. 
       // weakSelf is now set to nil.
       [myArray addObject:weakSelf];
    }
});
Run Code Online (Sandbox Code Playgroud)

这会因为向数组添加nil的NSInvalidArgument异常而崩溃.

在使用之前使引用变为强大可消除潜在的竞争条件并确保指针始终指向同一对象.

如果您100%确定某个对象只会被一个线程引用,则不一定要这样做.但做出这个假设是不好的做法.

  • 如果使用弱引用的唯一原因是避免保留周期,那么在块执行之前或期间弱引用变为零的任何情况都可能表示错误. (2认同)

ipm*_*mcc 6

它本身并不是必需的,但一般的想法是确保weakSelf在块执行时指向的对象不是dealloc'ed.创建强引用具有保留对象的副作用.当强引用超出范围时,ARC将释放该保留.这在很大程度上是防御性的.一般来说,您应该在块执行期间提供其他(更好)的保证,确保系统保持稳定.