如果我有自定义对象的NSMutableArray,我怎样才能轻松清除数组而不会导致任何内存问题?假设自定义对象类中有一个dealloc方法,它正确地释放了一个实例变量等。
例如,可以使用NSArray“removeAllObjects”方法吗?
如果是 - 这是如何工作的 - “removeAllObjects”在删除每个对象时调用“dealloc”方法
如果不是 - 最简单的方法是什么?
编辑(4回复后) - 在回复之后的最后一个澄清问题 - 我仍然不太确定我设置为保留的自定义对象中的实例变量/属性?这些似乎只能通过我的自定义对象类中的“dealloc”方法释放,我们手动执行此操作以及[super release]。
因此,如果重新清除数组,如果我执行removeAllObjects,然后NSArray向我的自定义对象发出“释放”,但不调用“dealloc”,那么我的实例变量如何被释放?
答案 0 :(得分:32)
removeAllObjects
将从数组中删除该对象。此过程将向对象发送释放消息,这将减少其引用计数。当引用计数达到零时,对象将被释放。
不要这样做,因为它会泄漏。
NSObject *object = [[NSObject alloc] init]; + 1
[array addObject:object]; + 1
[array removeAllObjects]; - 1
=======
= + 1 -> Leak
这是正确的方法:
NSObject *object = [[[NSObject alloc] init] autorelease]; + 1 (from alloc) - 1 (from autorelease)
[array addObject:object]; + 1
[array removeAllObjects]; - 1
=======
= 0 -> Object will be deallocated
您可以只释放数组,而不是调用removeAllObjects。如果一个数组被释放,那么它内部的所有东西都会被释放,如果没有对该对象的其他引用,它将被解除分配。
答案 1 :(得分:3)
是的,只需致电removeAllObjects
。可以肯定的是,在向数组添加对象或创建包含对象的数组时,不要调用retain
。这是自动完成的。
关于dealloc
,将再次自动完成,您无法预测何时。
你需要在dealloc中唯一拥有的是数组对象本身。也就是说,假设它是一个实例变量或ivar?
要检查一切正常,请使用Product运行Analyzer - >分析。然后使用Leaks仪器在应用程序中为应用程序提供配置文件,以检查您的代码是否都没有导致任何内存泄漏。
答案 2 :(得分:1)
永远不会直接调用dealloc
方法。一切都通过retain
/ release
机制(以及引用计数原则)完成。因此,这是被调用的release
方法,而不是直接调用dealloc
。如果最后dealloc
调用导致对象的引用计数(retainCount)达到零,则release
方法仅由运行时调用,这意味着该对象实际上已从内存中释放,因为没有人再使用它。
NSArray
并且Cocoa中的所有容器类(NSDictionary
,NSSet
,...)都会保留其值。因此,当您将objet添加到NSArray
之类的容器时,它将retain
该值。当你删除该值(包括调用removeAllObjects时),它将release
它。
内存管理规则很容易遵循:但唯一重要的规则是,如果您拨打release
,autorelease
或者alloc
,则只需拨打retain
或copy
alloc
方法。这始终是objet的责任,它使retain
/ copy
/ release
调用autorelease
/ alloc
。永远不要离开retain
/ copy
/ release
而没有待处理的autorelease
/ release
来平衡它(或者你会有泄漏),但另一方面如果您没有亲自拨打autorelease
/ alloc
/ retain
来电话,请勿拨打copy
/ MyClass* obj = [[MyClass alloc] init]; // here you do an alloc
[myArray addObject:obj]; // the NSArray "myArray" retains the object obj
// so now you can release it, the array has the responsability of the object while it is held in the array
[obj release]; // this release balance the "alloc" on the first line, so that's good
[myArray removeAllObjects]; // there the object held by the array receive a release while being removed from the array. As nobody retains it anymore, its dealloc method will be called automatically.
。
好榜样1:
MyClass* obj = [[MyClass alloc] init]; // here you do an alloc
[myArray addObject:obj]; // the NSArray "myArray" retains the object obj
// so now you can release it, the array has the responsability of the object while it is held in the array
[myArray removeAllObjects]; // there the object held by the array receive a release while being removed from the array. But your own code still retains a reference to it (because of the "alloc" on first line) so it won't be removed from memory right now
[obj release]; // this release balance the "alloc" on the first line, and as nobody retains the object anymore, its dealloc method will be called and it will be deallocated from memory
好榜样2:
MyClass* obj = [self getSomeObjectFromAnotherMethod]; // here you don't have an "alloc" on this line
[myArray addObject:obj]; // the array retains the object
[myArray removeAllObjects]; // the array release the object while it removes it from the array
// no need to call "release" here as there is no "alloc" done in the scope of this code
好榜样3:
MyClass* obj = [self getSomeObjectFromAnotherMethod]; // here you don't have an "alloc" on this line
[myArray addObject:obj]; // the array retains the object
[myArray removeAllObjects]; // the array release the object while it removes it from the array
[obj release]; // Crash here! obj does not exists anymore and has been deallocated from memory before this line!
错误的例子:
{{1}}
答案 3 :(得分:1)
基本上removeAllObjects
方法会向所有对象发送release
消息。 发布方法 减少对象引用计数 。如果对象的引用计数达到0
,则dealloc
消息将被发送到对象。
您的问题的答案是致电[array removeAllObjects]
是完全安全的。顺便说一下,如果你不再需要数组,你可以直接调用[array release]
来释放它的所有对象以及数组。