使用ARC和块时保留周期

时间:2013-12-02 10:13:57

标签: ios objective-c automatic-ref-counting objective-c-blocks retain-cycle

根据我的理解,当一个对象方法接收一个块作为完成参数时,我可以在块中发送“self”:

[object doMethodWithCompletion:^{
  [self doSomethingWhenThisMethodCompletes]
}];

但如果此对象“保留”该块(保存以供将来使用),我应该发送一份“弱”的自己副本:

__weak __typeof__(self) weakSelf = self;
object.savedBlock = ^{
  [weakSelf doSomethingWhenThisBlockIsCalledFromWithinObject];
};

但我也看到过变种,如:

__weak __typeof__(self) weakSelf = self;
object.savedBlock = ^{
  __typeof__(weakSelf) strongSelf = weakSelf;
  [strongSelf doSomethingWhenThisBlockIsCalledFromWithinObject];
};

我不清楚为什么/何时做最后一个变种

1 个答案:

答案 0 :(得分:5)

在块内创建一个强引用可确保如果块运行,则对象不会在块的中途解除分配,这可能会导致意外的,难以调试的行为。

typeof(self) weakSelf = self;
[anObject retainThisBlock:^{
    [weakSelf foo];
    // another thread could release the object pointed to by weakSelf
    [weakSelf bar];
}];

现在[weakSelf foo]会运行,但[weakSelf bar]不会,因为weakSelf现在是nil。如果在块内创建强引用,则在块返回之前无法释放该对象。