这是 Objective-C 中所有权术语的问题。最简单的规则是,如果在我们使用完对象后必须释放该对象,我们就拥有该对象。因此,所有者可以是一个类,可以是一个方法或一个函数,甚至是一个块,而且还有更多。同一个对象可能有多个所有者。
可以通过release 方法或autorelease 方法调用该版本。我们将它添加到自动释放池中以延迟它的释放,直到池被耗尽,这在大多数情况下是在运行循环结束时。您发布的代码与[[NSArray array]autorelease]; 有误,因为这会使您的应用程序由于过度释放而崩溃。正确的版本是[[NSArray new] autorelease];,这或多或少是静态方法array 返回的内容。
因此,如果我们暂时排除 autorelease,我们有 3 个元素:retain 将获得对象的所有权并增加保留计数,同时迫使您在某个时候释放它; release 将放弃所有权,减少保留计数,如果保留计数降至零(调用者是最后一个所有者),则可能释放对象;对象创建规则表明所有包含 create、alloc、new、copy... 的方法或函数将授予您所有权而不保留它们,并且您有责任显式调用它们的 release。
创建对象时,它的保留计数为 1。这意味着我们调用 alloc+init 的每个对象或其任何版本的保留计数都将为 1,并且需要显式释放。 [NSArray array] 等所有其他静态方法对[[[NSArray alloc] init] autorelease] 来说只是方便,需要保留这些方法才能接管所有权。
所以基本上如果你有一个类有一个数组指针NSArray *_array,并且我们想获得所有权,我们必须写_array = [someArray retain],在dealloc方法中我们必须写[_array release]。如果一个方法需要取得所有权,我们需要调用[someArray retain],当我们完成它时,我们需要调用[someArray release],除非我们返回对象本身,我们需要调用return [someArray autorelease]。这些是非常简单的规则,但在其他一些情况下,很难跟踪。因此,ARC 所做的就是将这些调用插入到您的代码中,您无需担心它们。与 ARC 之前一样,这些程序仍然存在。
所以 ARC 是如何插入这些调用的并没有真正解释,并且与版本不同。但是,如果我们再看一下您发布的示例,但让我们对其进行扩展:
- (NSArray *)foo // ARC version
{
NSArray *arr = [NSArray array];
for(NSObject *object in arr) NSLog(@"%@", object.description);
arr = [arr arrayByAddingObject:@"added something"];
return arr;
}
- (NSArray *)foo // ARC most likely behind the scenes
{
NSArray *arr = [[NSArray array] retain]; // reatin to claim ownership
for(NSObject *object in arr) NSLog(@"%@", object.description);
[arr autorelease]; // need to release it as it will be lost in the next line
arr = [[arr arrayByAddingObject:@"added something"] retain]; // the arr pointer now points to a different object. Claim the ownership of it
return [arr autorelease]; // need to relinquish the ownership
}
- (NSArray *)foo // standart non ARC wersion
{
NSArray *arr = [[NSArray alloc] init]; // we have the ownership by default
for(NSObject *object in arr) NSLog(@"%@", object.description);
NSArray *newArray = [[arr arrayByAddingObject:@"added something"] retain]; // need to explicitly retain this one as it is on the autorelease pool
[arr release]; // We do not need it anymore
return [newArray autorelease]; // need to relinquish the ownership
}