为什么弱/强舞会解决这个强大的参考周期?我不明白

时间:2016-04-01 20:18:58

标签: ios objective-c multithreading grand-central-dispatch

好的,我理解强烈弱舞的原因。

一个例子是,假设B强烈引用一个块,我们在B中设置该块以强引用它自己(B)。我们现在有B强烈引用我们的块,也许我们的块被分配给堆以便稍后运行(也许是异步),并且我们的块强烈引用B.假设只有一些对象A强引用B.如果我们杀了A,那么B - >块和块 - > B.强参考周期和内存泄漏。

我们可能会看到另一种方式是强烈引用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.不需要强弱的舞蹈。

然而,当我把弱强的舞蹈放进去......我们的问题得到了缓解。一个不再坚持。 (现在我们遇到的现实世界问题是留下视图并返回,继续创建新视图并保留以前的视图。每个人都会收听通知,并进行API调用。所以我们可能会有几十个API每隔一秒钟就会呼叫。)

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

1 个答案:

答案 0 :(得分:1)

假设A-doSomeBackgroundJazz:

的来电者

您的MySingleton类会将您的区块存储到属性中。

由于您在块中捕获了selfA),因此当块存储到属性中时,它也会被保留。

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

A并不保留sharedInstance并不重要,但无论出于何种原因,它显然都是悬而未决。

经验法则是,只要将块存储到属性中,就会self使用__weak。然而,总是进行__weak施放并不会造成伤害,很少有你想要一个块来保留一个对象的情况