强/弱的自我打破保持周期
我读过强/弱的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 – 我们在块前使用这个,
这只是指向自我,没有保留周期开始
– 当且仅当阻止将被执行时,保留将被执行
– >如果我们使它强大,那么它将开始保留周期,并将消耗内存,即使我们不叫块