2015-05-29 89 views
0

其大家都很熟悉的常见问题,但我还是不完全理解。父母子女建设保留周期

如果对象A拥有(具有强属性)对象B,而对象B具有对象A的强属性,则存在保留周期,并且不会释放对象并存在内存泄漏。

但是,如果对象A改为指向对象C而不是对象B,那么内存中的另一个地址呢?

据我所知,强大的性能做类似如下:

- (void)setObject:(id)newObject{ 
if (_newObject == newObject){ 
return; // 
} 

NSObject *oldObject = _newObject; 
_newObject = [newObject retain]; 
[oldObject release]; 
} 

那么,如果我们点而不是为对象C,是不是在这种情况下内存对象B将被释放?如果两个对象(A和B)将相反设置nil对象,该怎么办?内存泄漏是否还会有保留周期?在旧的价值“浮动”在内存的某个地方?

我知道,这已经讨论过很多次了,但我仍然无法在我的脑海中看到“全貌”。我很感谢在这方面的任何澄清。

+0

分配工具有助于辅助周期检测的工具。我建议你探索一下这些工具。如果你想编写示例代码来玩,创建你自己的NSObject子类,这样你就不会遇到静态实例(比如@“foo”)或标签指针。 – bbum

回答

2

您正在寻找的词是“保留周期”。

最简单的保留周期将是一个对自身有强烈参考的对象。非常罕见,因为它毫无意义。

最常见的情况是A对B和B有强烈的参考,对A有很强的参考A→B→A。你看到这个循环?

该循环可以是任何长度A-> B-> C-> D-> E-> F-> G-> - > A。这是一个保留周期,所以什么都不会发布。如果您只有A-> B-> C-> D - > ...-> Z且没有引用返回序列中的另一个对象,则不存在循环。没有周期,没有问题。

+0

所以,如果我们有循环A> B> A,然后我们做A> C和B> D,具有相同的强参考,那么就不会有内存泄漏,因此保留循环? –

+1

顺便说一句,那些对自身有强烈引用的对象并不少见,因为Swift中的对象可以有闭包作为它们的属性,一旦你访问了“self”的任何属性或方法,它就会强烈地引用“self”在那封闭之内。 Obj-C块也可以通过'self'导致保留周期,如下所示:http://stackoverflow.com/questions/4352561/retain-cycle-on-self-with-blocks?rq=1 –

+0

@EvgeniyKleban这两个答案和JeremyP的答案是正确的。 – bbum

3

如果问题是“你可以通过重新分配一个属性来打破保留周期吗?”,答案是肯定的。如果您将nil指定给属性,则同样适用。

+0

如果只是其中一个属性会被重新分配 - 设为零,这足以摆脱保留循环? –

+1

是的。因为当两者都相互引用时,循环存在。所以如果A - > B但是B - > NIL,你没有循环。但这都是学术性的,你应该使用强大的A-> B和弱的B-> A(或分配,但通常是弱的是合适的)。 –