嵌套块内引用弱引用

42

假设我已经创建了一个弱引用对象,使用方式为

__weak typeof(self) weakSelf = self;
[self doABlockOperation:^{
        ...
}];

在该块内,如果我嵌套另一个块:

[weakSelf doAnotherBlockOperation:^{
    [weakSelf doSomething];
}

它会创建一个保留周期吗?我需要创建另一个对weakSelf的弱引用吗?

__weak typeof(self) weakerSelf = weakSelf;
[weakSelf doAnotherBlockOperation:^{
    [weakerSelf doSomething];
}
2个回答

60

您的代码将能够正常工作:弱引用不会导致保留环,因为您明确指示ARC不增加弱对象的保留计数。但是,为了最佳实践,您应该使用弱引用创建对象的强引用。这也不会创建保留环,因为块内的强指针仅存在于块完成之前(其作用域仅限于块本身)。

__weak typeof(self) weakSelf = self;
[self doABlockOperation:^{
    __strong typeof(weakSelf) strongSelf = weakSelf;
    if (strongSelf) {
        ...
    }
}];

1
你能详细说明一下或者给我一些链接,解释为什么我应该使用弱引用来创建一个强引用对象吗?提供1或2个实际案例会非常有帮助。谢谢。 - Enzo Tran
3
它的好处是,当代码块执行时,你可以安全地检查对象是否仍然存在。否则,你将调用 nil,这意味着你的代码块不会有太多作用。我建议你观看此视频WWDC 2012 ;)。 - Gianluca Tranchedone
1
@EnzoTran:你想创建一个强引用,因为弱引用只是“安全”的,因为你知道self在块执行时仍将是一个有效的对象。但是,不能保证它不会在内部块执行时被释放,这就是为什么它应该捕获一个强引用的原因。 - newacct
5
这是一篇博客文章,其中有一个很好的关于这种模式的解释:http://dhoerl.wordpress.com/2013/04/23/i-finally-figured-out-weakself-and-strongself/。 - smileyborg
3
在代码块中,指向强引用的指针仅在该代码块完成前存在。+1表示同意这个说法。 - onmyway133
显示剩余2条评论

19

这要看情况。

只有在你实际存储块时(因为 self 指向块,而块指向 self),才会创建保留循环。如果您不打算存储任何块,则使用对 self 的强引用就足够了 --- 块将在执行后首先被释放,然后它会释放其指向 self 的指针。

在您特定的示例中,除非您执行未显示的更多操作,否则不需要创建任何更弱的WeakerEvenWeakerSelfs。


我理解如果self保留了block,那么需要弱引用。但是我需要使用哪些操作,才会需要弱引用呢? - Enzo Tran
1
实际上,我认为你永远不需要weakerSelfs - 弱指针被标记为不增加引用计数,因此没有办法使它更“弱”。 - George Karpenkov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接