为啥弱/强之舞解决了这个强参考循环?我不明白

Posted

技术标签:

【中文标题】为啥弱/强之舞解决了这个强参考循环?我不明白【英文标题】:Why does the weak/strong dance solve this strong reference cycle? I don't understand为什么弱/强之舞解决了这个强参考循环?我不明白 【发布时间】:2016-04-01 20:18:58 【问题描述】:

好的,我明白强弱舞的原因了。

一个例子是,假设 B 强引用一个块,我们将 B 内部的块设置为强引用自身 (B)。我们现在有 B 强引用我们的块,也许我们的块被分配到堆以稍后运行(可能是异步的),并且我们的块强引用 B。假设只有某个对象 A 强引用 B。如果我们杀死 A,那么 B -> 块 AND 块 -> B. 强引用循环和内存泄漏。

我们可能看到的另一种方式是 A 强引用 B。B 强引用 C。也许 C 有一个块属性,而 B 说 C.block = ^ self.blah = blah 。现在我们有 B 强引用 C,C 强引用 B。A 被杀死,我们又一次有一个强引用循环。如果我在这方面有任何错误,请纠正我。

现在我看到了一个强参考周期,在我看来不应该是一个强参考周期。

我有一个类,我们称它为 A。A 有一个函数 fooBar。在 fooBar 内部,我们调用

[[MySingleton sharedInstance] doSomeBackgroundJazz: ^
    self.blah = blah;
];

我们看到了一个强大的引用周期,并且 A 没有被释放。现在,在我看来,A 并没有强烈引用 MySingleton。也许在 fooBar 的持续时间内它会这样做,但类本身不会。但是当 fooBar 完成后,它会从堆栈中删除,并且不再有对 MySingleton 的引用。如果我在这里的任何时候错了,请纠正我。现在,我们知道 [MySingleton doSomeBackgroundJazz] 中的块代码强烈引用 A。但是,为什么这很重要? A 没有引用 MySingleton。 MySingleton 强烈引用 A. 不需要弱强舞。

然而,当我把弱强的舞蹈放进去时……我们的问题得到了缓解。 A不再停留。 (现在我们遇到的现实问题是离开一个视图然后回来,继续创建一个新视图并保留以前的视图。每个视图都监听一个通知,并执行一个 API 调用。所以我们可能有几十个 API每秒都有电话发出)。

为什么弱强舞能解决这个问题?

【问题讨论】:

如果没有真正的代码来证明您的问题,问题就毫无意义。在不创建保留循环或削弱任何东西的情况下,当然可以在 sn-p 中做你自己的事情。 【参考方案1】:

假设A 是您对-doSomeBackgroundJazz: 的调用者

您的MySingleton 类似乎将您的块存储到一个属性中。

因为您在块中捕获了self (A),所以当块存储到属性中时,它也会被保留。

所以这意味着只要您的单例实例 (sharedInstance) 被保留,它的块属性就会被保留,因此您捕获的 A 也会被保留。

A 不保留sharedInstance 并不重要,它显然是出于某种原因而徘徊。

经验法则是将块存储到属性中时将self 转换为__weak。但是,无论如何总是进行__weak 强制转换并没有什么坏处,您希望块保留对象的情况很少发生

【讨论】:

以上是关于为啥弱/强之舞解决了这个强参考循环?我不明白的主要内容,如果未能解决你的问题,请参考以下文章

为啥说 Python 是强类型语言

存储弱参考有时会导致泄漏

块中具有强引用的弱变量:不创建保留循环?

强类型与静态类型以及弱类型与动态类型之间的区别

有啥办法可以让 JS 强类型化?

java nio 方面的,我不明白while(true)表示啥?