在嵌套块中引用弱自我

Posted

技术标签:

【中文标题】在嵌套块中引用弱自我【英文标题】: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];

【问题讨论】:

【参考方案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 - 弱指针被标记为不增加引用计数,因此无法使其“更弱”。

以上是关于在嵌套块中引用弱自我的主要内容,如果未能解决你的问题,请参考以下文章

闭包中的弱自我和后果示例

ARC:没有调用 Dealloc

实现 API 时如何避免在块中捕获自我?

在此块中强烈捕获自我可能会导致保留周期

在块、核心数据、swift中使用弱、强的自我使用

块中具有强引用的弱变量:不创建保留循环?