dealloc
方法從不直接調用。一切都通過retain
/release
機制(和引用計數原理)完成。所以這是被調用的release
方法,而不是直接的dealloc
。該dealloc
方法由運行時,如果最後release
調用導致對象的引用計數(retainCount)達到零,這意味着真正的對象從內存中沒有人使用它了釋放只叫。
NSArray
和Cocoa中的所有容器類(NSDictionary
,NSSet
,...)都保留它們的值。因此,當您向像NSArray
這樣的容器添加對象時,該值將爲retain
。而當你刪除值(包括當你調用removeAllObjects「),它會release
它
內存管理的規則很容易遵循。但重要的是唯一的規則,你只需要調用release
或autorelease
如果你叫alloc
,retain
或copy
方法。這一直是該做的alloc
/retain
/copy
調用release
/autorelease
的客體的責任。切勿用alloc
/retain
/copy
沒有未決release
/autorelease
調用來平衡它(或者你將有泄漏),但另一方面從來沒有調用release
/autorelease
,如果你沒有做alloc
/retain
/copy
自稱。
好實施例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
[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.
良好實施例2:
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
良好實施例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
// no need to call "release" here as there is no "alloc" done in the scope of this code
爲例如:
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!
任何人都不應該叫'比內存管理器(或子類的'dealloc')dealloc'等。當removeAllObjects從數組中清除它時,removeAllObjects在每個對象上調用'release'。 –
是的,如果你在代碼中看到'dealloc'不是'[super dealloc]的一部分;'你做錯了。 –