【问题标题】:Referring to weak self inside a nested block在嵌套块中引用弱自我
【发布时间】:2013-06-10 21:00:41
【问题描述】:

假设我已经创建了一个弱自我使用

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

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

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

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

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

【问题讨论】:

    标签: ios memory-management automatic-ref-counting block retain-cycle


    【解决方案1】:

    您的代码可以正常工作:弱引用不会导致保留循环,因为您明确指示 ARC 不要增加弱对象的 retainCount。然而,为了获得最佳实践,您应该使用弱引用创建对象的强引用。这也不会创建保留循环,因为块中的强指针只会在块完成之前存在(它的唯一范围是块本身)。

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

    【讨论】:

    • 您能否详细说明一下或给我一些链接,说明为什么我应该使用弱引用创建对对象的强引用? 1或2个实际案例会有很大帮助。谢谢。
    • 它的好处是,当块执行时,您可以安全地检查对象是否仍然存在。否则你会调用 nil,这意味着你的块不会做太多。我建议你看this video from the WWDC 2012 ;)。
    • @EnzoTran:你想创建一个强引用,因为弱引用是“安全的”,只是因为你知道 self 在块执行时仍然是一个有效的对象。但是不能保证在内部块执行时它不会被释放,这就是它应该捕获强引用的原因。
    • 这是一篇博文,对这种模式有另一个很好的解释:dhoerl.wordpress.com/2013/04/23/…
    • +1 表示“块内的强指针仅在块完成之前存在”
    【解决方案2】:

    视情况而定。

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

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

    【讨论】:

    • 所以我理解如果例如 self 保留块,则需要关于弱自我的部分。但是我可以执行什么样的操作,我需要weakerSelf?
    • 实际上,我认为您永远不需要weakerSelfs - 弱指针被标记为不增加引用计数,因此无法使其“更弱”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-01
    • 2016-11-25
    相关资源
    最近更新 更多