我在这里看到了防止块保留周期的解决方案
但是我很难理解它为什么或什至是如何工作的。
在示例中,进行了弱自引用并对其进行了操作。我可以看到这是如何打破循环的。但是,在块内会创建一个强引用。这不会重新创建我们最初试图阻止的保留周期吗?
比如说self是0x123,那么weakself也指向0x123。然后 strongSelf 将在块内设置为 0x123。
这不会形成一个保留循环吗?(self 对 block 有很强的引用,而 strongSelf 对 self 有很强的引用)
我在这里看到了防止块保留周期的解决方案
但是我很难理解它为什么或什至是如何工作的。
在示例中,进行了弱自引用并对其进行了操作。我可以看到这是如何打破循环的。但是,在块内会创建一个强引用。这不会重新创建我们最初试图阻止的保留周期吗?
比如说self是0x123,那么weakself也指向0x123。然后 strongSelf 将在块内设置为 0x123。
这不会形成一个保留循环吗?(self 对 block 有很强的引用,而 strongSelf 对 self 有很强的引用)
在块内创建了一个强引用。这不会重新创建我们最初试图阻止的保留周期吗?
是的,确实如此,但只是暂时的。初始化时strongSelf
,它形成对当前weakSelf
值的强引用。(或者为零,如果该对象已被释放。)一旦块完成运行,这个(本地)强引用将被释放,从而打破循环。
问题不是保留周期本身(它们一直在发生),而是一个长期存在的保留周期,它使对象的存活时间比预期的要长。
比如说self是0x123,那么weakself也指向0x123。然后 strongSelf 将在块内设置为 0x123。这不会形成一个保留周期吗?
实际上,没有;它们并非都直接指向同一事物。事实是 ARC 弱引用确实(在幕后)将一个额外的对象插入到混合中。我们称它为暂存器对象。它给人一种我们指向同一个对象的错觉,但我们实际上是通过暂存器对象指向的,它不会保留它所指向的东西。这就是 ARC 弱引用的工作原理(也称为归零弱引用);它们涉及特殊的额外中间暂存器对象,这些对象可以在不保留自身的情况下保留,从而破坏了链条。
在一个保留循环中,A 在 B 上有一个保留,B 在 A 上有一个保留。每个人都会在自己的另一个上释放dealloc
,但那一刻永远不会到来。
在块的情况下,A 是self
,B 是块。self
无论出于何种原因在块上放置一个保留(通常相当模糊,与复制、观察者等有关;它并不总是发生,事实上它发生的几率比大多数人想象的要少得多) . self
该块仅仅因为它是一个闭包并且self
在块中被引用这一事实而放置了一个保留。
但是通过做弱-强舞,我们可以防止这种情况发生。传入块的是weakself
,它实际上是通过暂存器对象的引用。该块可以保留 this,但反过来,它不保留self
。因此没有保留周期。