[英]NSMutableArray property - Release children
这是运行以下代码时看到的内容:
// Dealloc on MyClass not called
MyClass* c = [MyClass new];
self.a = [NSMutableArray new];
[self.a addObject:c];
[c release];
[a release];
// Dealloc on MyClass called
MyClass* c2 = [MyClass new];
NSMutableArray* a2 = [NSMutableArray new];
[a2 addObject:c2];
[c2 release];
[a2 release];
// Dealloc on MyClass called
MyClass* c3 = [MyClass new];
a = [NSMutableArray new];
[a addObject:c3];
[c3 release];
[a release];
为什么在第一个示例中未调用dealloc?
编辑:
我想我误会了这一切。 基本上我需要做的是:
NSMutableArray* alocal = [NSMutableArray new]; // alocal has a retain count of 1
self.a = alocal; // a has a retain count of 1
[alocal release]; // alocal has a retain count of 0
[a release]; // a has a retain count of 0
要么
self.a = [[NSMutableArray new] autorelease]; // a has a retain count of 2
[a release]; // a has a retain count of 0
要么
self.a = [NSMutableArray array]; // a has a retain count of 2
[a release]; // a has a retain count of 0
请注意,使用自动释放/数组选项(#2和#3),不会立即释放a,因此,如果要更多控制,请使用选项#1。
谢谢!
因为在第一个示例中,假设a
是保留/复制属性,所以数组会泄漏。
self.a = [NSMutableArray new];
顺便说一下,这与第三个示例不同:
a = [NSMutableArray new];
在第三种情况下,将对象直接分配给ivar(不涉及属性设置器)。
回到第一个示例, new
方法返回一个保留的对象(+1),然后属性设置器也保留该对象(+2)。 然后,释放该属性(-1)时,您最终得到+1。 这是错的。 您需要平衡保留/释放数,以+0结尾。
一个简单的解决方案是使用便捷构造函数 :
self.a = [NSMutableArray array];
在这种情况下,方法array
将返回一个自动释放的对象(+0),而属性设置器将保留该对象(+1),该对象由释放属性(-1)平衡,最后得到+0。
同样,在第一个示例中,您通过ivar释放设置为属性的对象:
[a release];
结果,该属性现在持有指向潜在释放对象的指针。 由于您放弃了该对象的所有权,因此无法保证该对象将来会存在。 如果实际上已释放了该对象(因为它没有任何其他所有者),则指针仍将指向该对象以前所在的堆中的内存地址; 除了现在,该地址可能包含任何内容:所述对象或无关对象的旧位模式或绝对垃圾。
如果将消息发送到已释放的对象,则不会发生任何事情,例如,它将使您的应用程序崩溃。 为避免这种情况,请通过属性释放对象:
self.a = nil;
这取决于您如何实现属性“ a”,它应该是:
@property (retain) NSMutableArray *a;
同样在使用'new'时它会分配分配,因此您应该像这样自动释放它:
self.a = [[NSMutableArray new] autorelease];
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.