用强弱自我打破保留周期

som*_*ong 10 cocoa objective-c ios automatic-ref-counting

我已经阅读了关于强/弱的帖子self来打破保留周期,但我仍然对它们是如何工作感到困惑.我理解使用__weak typeof(self) weakSelf = self创建弱自我的参考,但我对强引用感到困惑.据我了解,强引用是有一个强引用,self以便它不会在块结束之前解除分配吗?那么为什么有必要__strong typeof(self) strongSelf = weakSelf呢?这最终是否指向自我对象?那么为什么不strongSelf = self呢?

Jef*_*ing 13

在块中引用的任何非弱对象都将导致在创建块时对该对象进行隐式保留.没有执行,但已创建.

如果您直接从self初始化内部strongSelf,您将保留self的值并可能导致保留周期.

另一方面,如果从weakSelf初始化它,则不会保留weakSelf的值.

这就是两步的原因.外部代码将self的值复制到weakSelf中,但ARC不会添加retain,因为它是__weak().

块"创建"复制weakSelf的值(或者至少设法在执行时使其值可用).你无法看到它复制到哪里,但确实如此.

在块"执行"时,块复制"weakSelf的值"(如果self已经被平均释放,则为nil)为strongSelf,然后ARC将保留应用于.因此,对于块的持续时间,strongSelf引用的对象将保持活动状态,如果它始终处于活动状态.如果你只依赖于weakSelf,那么在执行块期间它可能会随时变为零.

注意弱/强模式是带括号 - 许多例子实际上依赖于weakSelf将为零的事实,并且该块将默默地成为无操作的集合(消息为零).

保留周期通常只发生在以下情况下:(a)您在self.property中保留对块的引用;或者(b)将块移交给其他对象(通知管理器等),并告诉其他对象忘记它你的dealloc; 在这两种情况下,当块处于活动状态时,永远不会调用dealloc.

当人们说"做这些事情的方式是弱势/强势模式"时,他们会假设最糟糕的情况.


Rob*_*Rob 11

模式是:

__weak typeof(self) weakSelf = self;

[manager someAsynchronousMethodWithCompletionHandler:^{
    typeof(self) strongSelf = weakSelf;
    if (strongSelf) {
        ...
    }
}];
Run Code Online (Sandbox Code Playgroud)

这个想法是完成处理程序块只有一个弱引用self,因此如果self在调用完成块之前释放if ,那么它将被安全地释放,因为该块没有强引用.(一个常见的例子是,当视图控制器发起一些异步网络请求来更新视图时,如果视图控制器在网络请求完成之前被解除,那么对于一个早已消失的视图,没有必要挂在视图控制器实例上.)

但是,这个weakSelf/ strongSelf模式还确保如果相反的情况发生,即完成块已经启动并且strongSelfself释放之前遇到该行,则该块将确保self在该块的运行期间保留(即它无法获得)在完成块运行的一半时解除分配,即使它在另一个线程上运行).这具有许多潜在的好处(从对象完整性到消除竞争条件).有时你实际上并不需要strongSelf" weakSelf/ strongSelfdance" 的一半,但它在需要时是一个非常宝贵的工具.

但是,如果你有提到块内的线路,typeof(self) strongSelf = self(代替weakSelf),仅仅出现self在该语句的右边会导致块保持强引用self了前面,完全击败利用的目的weakSelf在第一名.

  • 我认为你没有正确的模式.强自我与自我的内在分配应该来自弱者. (3认同)