例如,如果您的对象允许设置它的main Sprocket,您可以这样实现setMainSprocket:方法:
– (void)setMainSprocket:(Sprocket *)newSprocket {
[mainSprocket autorelease];
mainSprocket = [newSprocket retain]; /* Claim the new Sprocket. */
return;
}
现在,setMainSprocket:可能在被调用时带一个Sprocket对象的参数,而调用者想要保留该Sprocket对象,这意味着您的对象将
与其他对象共享Sprocket。如果有其他对象修改了Sprocket,您的对象的main Sprocket也会发生变化。但如果您的Thingamajig需
要有属于它自己的Sprocket,您可能会认为该方法应该复制一份私有的副本(您应该记得复制也会得到所有权):
– (void)setMainSprocket:(Sprocket *)newSprocket {
[mainSprocket autorelease];
mainSprocket = [newSprocket copy]; /* Make a private copy. */
return;
}
以上几种实现方法都会自动释放原来的main sprocket。如果newSprocket和mainSprocket是同一个的对象,并且Thingamajig对
象是它的唯一所有者的话,这样做可以避免一个可能出现的问题:在这种情况下,当sprocket被释放时,它会被立即回收,这样一旦
它被保留或复制,就会导致错误。下面的实现也解决了这个问题:
– (void)setMainSprocket:(Sprocket *)newSprocket {
if (mainSprocket != newSprocket) {
[mainSprocket release];
mainSprocket = [newSprocket retain]; /* Or copy, if appropriate. */
}
}
在所有这些情况中,看起来好像最终为您的对象设置的mainSprocket泄漏了,因为您不用释放对它的所有权。这些由dealloc方法
负责,在“回收对象”部分进行了介绍。“存取方法”部分更详细地描述了存取方法及其实现。
回收对象
当一个对象的保留计数减少至0时,它的内存将被收回—在Cocoa术语中,这被称为“释放”(freed)或“回收”(deallocated)。当一
个对象被回收时,它的dealloc方法被自动调用。dealloc方法的作用是释放对象占用的内存,释放其持有的所有资源,包括所有实
例变量对象的所有权。
如果在您的类中有实例变量对象,您必须实现一个dealloc方法来释放它们,然后调用超类的dealloc实现。例如,如果
Thingamajig类含有mainSprocket和auxiliarySprocket实例变量,您应该这样实现该类的dealloc方法:
- (void)dealloc {
[mainSprocket release];
[auxiliarySprocket release];
[super dealloc];
}