2011-10-09 36 views
1

这是我所看到的,当我运行下面的代码:NSMutableArray的财产 - 发行儿童

// 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 

OR

self.a = [[NSMutableArray new] autorelease]; // a has a retain count of 2 
[a release]; // a has a retain count of 0 

OR

self.a = [NSMutableArray array]; // a has a retain count of 2 
[a release]; // a has a retain count of 0 

正如一个音符,与自动释放/阵列选项(#2,#3), a不会马上释放,所以如果你想要更多的控制,请使用选项#1。

谢谢!

+0

有趣的...所以基本上你希望它在那一刻被释放吧?这听起来很公平。通常我们只是让游泳池自动释放,但你是对的,它不会立即释放。 – raixer

回答

3

因为在第一个例子中,假设a是保留/复制属性,数组泄漏。

self.a = [NSMutableArray new]; 

其中,顺便说一句,与第三实施例不同:

a = [NSMutableArray new]; 

在第三种情况下,对象被直接分配到的ivar(不涉及属性setter)。

回到第一个例子,方法new返回一个保留对象(+1),然后属性设置器保留对象(+2)。然后,当财产被释放(-1)时,你最终得到+1。这是错误的。你需要平衡你的保留/释放以+0结束。

一个简单的解决方案是使用一个便捷构造

self.a = [NSMutableArray array]; 

在这种情况下,返回array一个自动释放物体(0)和属性setter的方法保留了对象(1),这是由财产释放(-1)平衡,你最终+0。


此外,在第一示例中,您松开穿过的ivar设置的属性的对象:

[a release]; 

其结果是,该属性现在保持一个指针到一个潜在的解除分配对象。由于您放弃了对象的所有权,因此不能保证该对象将来还活着。如果该对象实际上已被释放(因为它没有任何其他所有者),则您的指针仍将指向该对象曾经居住的堆的内存地址;除了现在,该地址可能包含任何内容:所述对象的旧位模式或不相关对象或绝对垃圾。

如果您将消息发送到释放对象,例如,它会让你的应用崩溃。为了避免这种情况,通过属性释放对象:

self.a = nil; 
+0

当我做... self.a = [NSMutableArray数组]; dealloc仍然没有被调用。另外当我调用... self.a = [[NSMutableArray new] autorelease]; dealloc仍然没有被调用。 – user472292

+0

@ user472292既然数组不再泄漏,它应该被调用。必须有其他事情正在进行。你能提供更多细节吗? – albertamg

+0

我很确定阵列没有泄漏。在我打电话给[发布]之前,我检查了保留计数,结果为1. – user472292

0

这取决于你如何实现财产“A” 它应该是:

@property (retain) NSMutableArray *a; 

也使用“新”它是把分配,所以你应该自动释放它像这样的时候:

self.a = [[NSMutableArray new] autorelease]; 
+0

当我做... self.a = [NSMutableArray数组]; dealloc仍然没有被调用。另外当我调用... self.a = [[NSMutableArray new] autorelease]; dealloc仍然没有被调用。 – user472292