强烈引用块内的弱引用

时间:2014-05-22 12:25:41

标签: ios objective-c objective-c-blocks

为什么有必要对块内的弱引用进行强引用?

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

背景
正如Mason所述,这是最佳做法。

  

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

示例:

__weak typeof(self) weakSelf = self;
void (^someBlock)(id) = ^(id data){
    typeof(self) strongSelf = weakSelf;
    // code using strongSelf
});

2 个答案:

答案 0 :(得分:14)

想象一下,对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];
    }
});

这会因NSInvalidArgument异常而崩溃,无法将nil添加到数组中。

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

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

答案 1 :(得分:6)

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