Objective-C不可变对象copyWithZone:与ARC兼容的实现

时间:2012-02-03 10:33:07

标签: objective-c cocoa copy automatic-ref-counting

正如我所假设的,这应该适用于ARC下的不可变对象:

- (id) copyWithZone:(NSZone *)zone {
    return self;
}

但如果我需要深层复制,我应该写这样的东西:

- (id) copyWithZone:(NSZone *)zone {
    Immutable *copy = [[Immutable alloc] initWithStr:str];
    return copy;
}

所以,如果我认为是正确的,ARC会理解情况(1)和(2)并做出关于“+1”的正确决定。

我是对的吗?

2 个答案:

答案 0 :(得分:12)

似乎我是对的:我找不到任何关于主题的具体文档,但是我在关闭ARC的情况下创建单独的测试项目,然后选择迁移到ARC。这是没有ARC的代码:

- (id) copyWithZone:(NSZone *)zone {
    return [self retain];
}

这是我在迁移后得到的:

- (id) copyWithZone:(NSZone *)zone {
    return self;
}

ARC有时会起作用,但似乎我们应该相信它会很好地完成它。 : - )

答案 1 :(得分:4)

自动引用计数as stated in the specification遵循标准的Cocoa命名实践。这意味着假设前缀为initcopynew的方法返回调用者拥有的对象(+1引用计数)。因此,如果从其中一个方法返回一个对象,ARC会自动以这种方式处理它,因为您不再能够明确地保留它。

Apple指出的一个有问题的案例是使用手动引用计数代码的第三方框架,其中作者没有遵循标准命名约定。他们给出的一个示例是返回名为copyRightString的自动释放字符串的方法。这将在ARC上过度发布,因为它将假设从这种方法返回+1引用计数对象。

您可以使用以下修饰符强制ARC以特殊方式处理此方法:

-(NSString*) copyRightString NS_RETURNS_NON_RETAINED;

Mugunth Kumar在his ARC migration writeup中有更多细节。