在initWithCoder中使用retain?

时间:2009-10-30 14:26:37

标签: objective-c cocoa

我正在阅读有关编码和解码的内容,我注意到有时人们会错过最后的保留,我也注意到保留有时会用在一些可用的但不是其他的。我可以问......

(1)此保留的目的是什么?为什么有时不需要?

(2)使用保留是否意味着我需要将其与版本匹配,如果是这样的话?

- (id) initWithCoder: (NSCoder *) decoder {
    name  = [[decoder decodeObjectForKey: @"CardName"] retain];
    email = [[decoder decodeObjectForKey: @"CardEmail"] retain];
}

- (id) initWithCoder: (NSCoder *) decoder {
    name  = [decoder decodeObjectForKey: @"CardName"];
    email = [decoder decodeObjectForKey: @"CardEmail"];
}

加里

2 个答案:

答案 0 :(得分:12)

您的第一个snippit表示正确的行为。 -decodeObjectForKey:方法不包含单词initcopynew,因此没有承诺返回的对象是否会保留,如果是,长。如果你的对象需要它的ivars留在周围,它应该-retain它从解码器返回的对象。这个-retain需要与-release进行平衡,-dealloc将在您的对象的- (void)dealloc { [name release]; [email release]; [super dealloc]; } 方法中(因此该对象是使用它保留的一些初始ivars创建的,并且它会释放其ivars当它被摧毁时)。像这样:

assign

不需要保留/释放舞蹈:

  • 如果您正在使用垃圾收集

  • 如果您的对象不需要声明其ivars的所有权。情况并非如此;代理通常不会被保留(但通常也不会被存档),并且使用{{1}}修饰符声明的属性也不是。

答案 1 :(得分:9)

您也可能被使用过属性的人误导了。您可能已经看到过人们在做:

- (id) initWithCoder: (NSCoder *) decoder {
    self.name  = [decoder decodeObjectForKey: @"CardName"];
    self.email = [decoder decodeObjectForKey: @"CardEmail"];
}

如果名称和电子邮件被定义为“保留”属性,那就没问题。当然,你接下来的论点是关于在初始化/ dealloc方法中使用属性访问器是否合法/可行 - 有些人说是,有些人说不,Apple似乎站在没有但是从未真正给过我能看到的充分理由。