强/弱的自我打破保持周期

我读过强/弱的self打破保留周期的post,但我仍然困惑,他们如何工作。 我明白使用__weak typeof(self) weakSelf = self来创build一个对自我的弱引用,但是我对强烈的引用感到困惑。 据我所知,强烈的参照是有一个强烈的self参照,以便它不会在块的权利结束之前被释放。 那么为什么有必要有__strong typeof(self) strongSelf = weakSelf ? 这不就结束了指向自己的对象吗? 那么,为什么不strongSelf = self呢?

在块内引用的任何非弱对象都将导致该对象上的隐式保留,因为该块正在创build。 不执行,但创build。

如果你直接从自我中初始化内在的强者,你将保留自我的价值并可能导致一个保留周期。

另一方面,如果你从weakSelf初始化,你将不会保留weakSelf的价值。

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

“创build”块复制weakSelf的值(或者至less在执行时设置它的值)。 你看不到它复制到的地方,但它确实。

在块“执行”的时候,块复制“weakSelf的值”(如果自己已经被同时释放,它将为零)变成strongSelf,然后ARC将应用一个保留。 因此,在块的持续时间内,由strongSelf引用的对象将保持活着,如果它活着开始的话。 如果你只依靠弱自己,那么在执行这个块的过程中,任何时候都可能是零。

请注意,弱/强模式是腰带和大括号 – 很多例子实际上依赖于弱自我将会消失的事实,而块将默默地成为无操作(消息到零)的集合。

通常只有在以下情况下才会出现保留循环:(a)在self.property中保留对块的引用,或者(b)将该块closures到其他对象(通知pipe理器等),并告诉其他对象将其忘记你的dealloc; 在这两种情况下,你的dealloc将永远不会被调用,而块是活着的。

当人们说“做这个事情的方式是以弱/强模式”的时候,他们正在假设最坏的情况。

模式是:

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

这个想法是,完成处理程序块将只有一个self的弱引用,所以如果在完成块被调用之前释放self ,那么它将被安全地解除分配,因为该块没有强引用它。 (一个常见的例子是视图控制器启动一些asynchronousnetworking请求来更新视图,如果视图控制器在networking请求完成之前被解散,那么没有必要在视图控制器实例上挂一个已经很久的视图。)

但是,这种weakSelf / strongSelf模式也保证了如果相反的情况发生,完成块已经开始并且在self释放之前遇到strongSelf self行,块将确保self在该块的运行期间被保留(即即使在不同的线程上运行,也不能在完成块的运行过程中取消分配。 这具有许多潜在的好处(从对象完整性到消除竞争条件)。 有时你实际上并不需要“ weakSelf / strongSelf舞蹈”的strongSelf一半,但是在需要的时候,这是一个非常宝贵的工具。

但是,如果你在块内部有一行代码,那么typeof(self) strongSelf = self (而不是weakSelf ),那么在这个陈述的右边只存在self就会导致这个块保持强烈的self引用从weakSelf的使用目的。

有正确的答案,但我真的不知道,他们是否是你Q的答案。他们用一般的自我解释了保留周期的问题,但你的Q是:

那么,为什么不强壮自己呢?

这个问题的答案是:

如果有人愿意这样做,那么self就会成为这个街区封闭的一部分,而且总是被保留下来。 整个虚弱的自我将是毫无意义的。

简单地说

__weak typeof(self)weakSelf = self – 我们在块前使用这个,

这只是指向自我,没有保留周期开始

– 当且仅当阻止将被执行时,保留将被执行

– >如果我们使它强大,那么它将开始保留周期,并将消耗内存,即使我们不叫块