这如何防止阻塞保留周期?

时间:2014-07-07 20:31:26

标签: ios objective-c-blocks retain-cycle retained-in-memory

我看到了一个防止阻塞保留周期的解决方案here

但我无法理解为什么甚至是如何运作。

在这个例子中,一个弱的自我引用被作出并采取行动。我可以看到这是如何打破循环的。但是,在块中,会创建一个强引用。难道这不会重新创建我们首先想要阻止的保留周期吗?

比方说,自我是0x123 然后,weakself也指向0x123。 然后strongSelf会在块内设置为0x123 这不会成为一个保留周期吗?(自我强烈提及阻止和强自我有强烈的自我参考)

2 个答案:

答案 0 :(得分:1)

  

让我们假设自己是0x123然后,weakself也指向0x123。然后strongSelf会在块内设置为0x123。   这不会成为保留周期吗?

实际上,没有;他们并非都直接指向同一件事。事实上,ARC弱引用确实(在幕后)将一个额外的对象插入到混合中。我们称之为暂存器对象。它给出了我们指向同一个对象的幻觉,但实际上我们指的是通过的scratchpad对象,它没有保留它所指向的东西。这就是ARC弱引用的工作方式(也称为弱引用归零);它们涉及特殊的额外中间暂存器对象,可以在不保留的情况下保留,从而打破链条。

在一个保留周期中,A在B上有一个保留,B在A上有一个保留。每个都会在另一个dealloc上放一个版本,但那一刻永远不会到来。

在阻止情况下,A是self,B是块。无论出于什么原因,self都会保留该块(通常相当模糊,与复制,观察者等有关;它并不总是发生,事实上它比大多数情况更少发生人们似乎认为)。该块仅仅因为它是一个闭包并且在块中引用了self而在self上设置了保留。

但是通过做强弱的舞蹈,我们可以防止这种情况发生。进入该区块的是weakself, 这实际上是通过scratchpad对象的引用。该块可以保留此值,但它不会保留self。因此没有保留周期。

答案 1 :(得分:1)

  

在块中创建一个强引用。这不会重现   我们试图首先阻止的保留周期?

是的,确实如此,但只是暂时的。初始化strongSelf时,它会形成对当前weakSelf值的强引用。 (或者,如果该对象已被解除分配,则为零。)一旦块完成运行,将释放此(本地)强引用,从而打破循环。

问题不是保留周期本身(它们始终发生),而是长期保留周期,使其对象保持活动的时间超过预期。