在initWithCoder中使用retain?

fuz*_*oat 10 cocoa objective-c

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

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

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

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

要么

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

加里

小智 12

你的第一个snippit表示正确的行为.该-decodeObjectForKey:方法不包含单词init,copy或者new,因此没有任何关于返回的对象是否会保留在周围的承诺,如果有的话,则保留多长时间.如果你的对象需要它的ivars留在周围,它应该-retain从解码器返回的对象.这-retain将需要与a进行平衡-release,这将在您的对象的-dealloc方法中(因此对象是使用它保留的一些初始ivars创建的,并且在它被销毁时释放它的ivars).像这样:

- (void)dealloc {
  [name release];
  [email release];
  [super dealloc];
}
Run Code Online (Sandbox Code Playgroud)

不需要保留/释放舞蹈:

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

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


小智 9

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

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

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