为啥弱/强之舞解决了这个强参考循环?我不明白
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
强制转换并没有什么坏处,您希望块保留对象的情况很少发生
【讨论】:
以上是关于为啥弱/强之舞解决了这个强参考循环?我不明白的主要内容,如果未能解决你的问题,请参考以下文章