Ios 使用父子结构保留循环

Ios 使用父子结构保留循环,ios,objective-c,memory-management,memory-leaks,retaincount,Ios,Objective C,Memory Management,Memory Leaks,Retaincount,这是一个大家都熟悉的常见问题,但我仍然不完全理解 如果对象A拥有对象B(具有对象B的强属性),并且对象B具有对象A的强属性,则存在保留周期,并且不能释放任何对象,并且存在内存泄漏 但是,如果对象A将指向对象C而不是对象B,从而指向内存中的另一个地址,该怎么办 据我所知,强属性的作用如下: - (void)setObject:(id)newObject{ if (_newObject == newObject){ return; // } NSObject *oldObject = _newOb

这是一个大家都熟悉的常见问题,但我仍然不完全理解

如果对象A拥有对象B(具有对象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
object怎么办?是否仍存在内存泄漏的保留周期?旧值“浮动”在内存中的某个位置


我知道,这已经讨论过很多次了,但我仍然无法在脑海中了解“全貌”。我希望您能澄清此事。

您要找的词是“保留周期”

最简单的保留循环是一个对自身具有强引用的对象。非常罕见,因为这是毫无意义的

最常见的情况是A强引用B,B强引用A.A->B->A。你看到循环了吗


循环可以是任意长度的A->B->C->D->E->F->G->…->A。这是一个保留循环,因此不会释放任何内容。如果只有A->B->C->D->…->Z,并且没有引用序列中的另一个对象,那么就没有循环。没有循环,没有问题

你要找的词是“保留周期”

最简单的保留循环是一个对自身具有强引用的对象。非常罕见,因为这是毫无意义的

最常见的情况是A强引用B,B强引用A.A->B->A。你看到循环了吗


循环可以是任意长度的A->B->C->D->E->F->G->…->A。这是一个保留循环,因此不会释放任何内容。如果只有A->B->C->D->…->Z,并且没有引用序列中的另一个对象,那么就没有循环。没有循环,没有问题

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

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

因此,如果我们有循环A>B>A,然后我们使用相同的强引用执行A>C和B>D,则不会出现内存泄漏,因此会保留循环?顺便说一句,对自身具有强引用的对象在现在并不罕见,因为Swift中的对象可以将闭包作为其属性,一旦您访问该闭包中的
self
的任何属性或方法,它将捕获对
self
的强烈引用。Obj-C块也可以引起带有
self
的retain循环,如下所述:@EvgeniyKleban这个答案和JeremyP的答案都是正确的。因此,如果我们有循环A>B>A,然后我们用相同的强参考值做A>C和B>D,不会有内存泄漏,因此保持循环?顺便说一句,对自身具有强引用的对象在当时并不罕见,因为Swift中的对象可以将闭包作为其属性,一旦您访问闭包中的任何属性或方法,就会捕获对
self
的强引用。Obj-C块也会导致带有
self
的retain循环,如下所述:@EvgeniyKleban此答案和JeremyP的答案都是正确的。如果仅将其中一个属性重新分配-设置为nil,则足以消除retain cyrcle?是的。因为当两者相互引用时,循环就存在了。所以如果A->B但是B->NIL,你没有循环。但这都是学术性的,你应该使用强a->B和弱B->a(或赋值,但通常弱是合适的)。如果只将其中一个属性重新赋值-设置为nil,就足以去掉保留环圈?是的。因为当两者相互引用时,循环就存在了。所以如果A->B但是B->NIL,你没有循环。但这都是学术性的,你应该使用强a->B和弱B->a(或赋值,但通常弱是合适的)。分配工具有助于周期检测的工具。我建议您探索上述工具。如果您想编写示例代码,请创建自己的
NSObject
子类,这样您就不会遇到静态实例(如@“foo”)或标记指针。分配工具具有帮助循环检测的工具。我建议您探索上述工具。如果您想编写示例代码,请创建自己的
NSObject
子类,这样您就不会遇到静态实例(如@“foo”)或标记指针。