请参阅避免导致您在高级内存管理中使用的对象的重新分配:实用内存管理,其中他们指出“接收到的对象通常应该在整个调用方法的范围内保持有效”,即retain
并且release
不是必需的,除非使用以下警告:
这条规则偶尔会有例外,主要属于两个类别之一。
从基本集合类之一中删除对象时。
heisenObject = [array objectAtIndex:n];
[array removeObjectAtIndex:n];
// heisenObject could now be invalid.
当一个对象从一个基本集合类中移除时,它会被发送一个release
(而不是autorelease
)消息。如果集合是被移除对象的唯一所有者,则被移除对象(heisenObject
在示例中)会立即被释放。
当一个“父对象”被释放时。
id parent = <#create a parent object#>;
// ...
heisenObject = [parent child] ;
[parent release]; // Or, for example: self.parent = nil;
// heisenObject could now be invalid.
在某些情况下,您从另一个对象中检索一个对象,然后直接或间接释放父对象。如果释放父级导致它被释放,并且父级是子级的唯一所有者,那么子级(heisenObject
在示例中)将同时被释放(假设它发送的是释放而不是autorelease
消息父母的dealloc
方法)。
为了防止出现这些情况,您heisenObject
在收到它时保留它,并在完成后释放它。例如:
heisenObject = [[array objectAtIndex:n] retain];
[array removeObjectAtIndex:n];
// Use heisenObject...
[heisenObject release];
如果您的辅助功能属于这些类别之一,我会感到惊讶。retain
如果没有and ,你可能会很好release
,但我只是为了充分披露而提及它。
显然,您可能需要自己的retain
,release
如果您的函数出于其他原因需要它(例如,如果任务是异步的,或者如果您正在做一些不寻常的事情,对象必须超出调用方法的范围),但我怀疑您会提到如果你在做这些事情之一。
此外,如果您的实用程序函数正在创建和返回一个对象,那将是另一回事(例如,您通常会autorelease
返回要返回的对象)。