Objective c 在initWithCoder中使用retain?

Objective c 在initWithCoder中使用retain?,objective-c,cocoa,Objective C,Cocoa,我正在阅读有关编码和解码的内容,我注意到有时人们会错过结尾处的retain,我还注意到retain有时用于某些变量,但不用于其他变量。我能问一下 (1)此保留的目的是什么,为什么有时不需要它? - (id) initWithCoder: (NSCoder *) decoder { name = [[decoder decodeObjectForKey: @"CardName"] retain]; email = [[decoder decodeObjectForKey: @"C

我正在阅读有关编码和解码的内容,我注意到有时人们会错过结尾处的retain,我还注意到retain有时用于某些变量,但不用于其他变量。我能问一下

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

- (id) initWithCoder: (NSCoder *) decoder {
    name  = [[decoder decodeObjectForKey: @"CardName"] retain];
    email = [[decoder decodeObjectForKey: @"CardEmail"] retain];
}
(2)使用retain是否意味着我需要将其与发行版匹配,如果需要,在哪里匹配?

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


加里

你的第一个短发代表了正确的行为。
-decodeObjectForKey:
方法不包含单词
init
copy
new
,因此没有承诺返回的对象是否会保留,如果保留多长时间。如果您的对象需要它的IVAR留在周围,它应该保留它从解码器返回的对象。此
-retain
需要与
-release
平衡,这将在对象的
-dealloc
方法中进行(因此创建对象时会保留一些初始IVAR,并在销毁时释放其IVAR)。像这样:

- (void)dealloc {
  [name release];
  [email release];
  [super dealloc];
}
不需要保留/释放舞蹈:

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

  • 如果您的对象不需要声明其IVAR的所有权。这种情况并不常见;委托通常不会被保留(但通常也不会被存档),使用
    assign
    修饰符声明的属性也不会被保留


    • 您也可能被使用房产的人误导。你可能见过人们这样做:

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

      如果名称和电子邮件被定义为“保留”属性,那就好了。当然,接下来你会开始讨论在初始化/解除锁定方法中使用属性访问器是否合法/明智——有人说是,有人说不是,苹果似乎站在了反对的一边,但我从来没有真正给出一个我能看到的好理由。

      我可能需要再次了解一下内存管理指南,可以问一下吗,如果我分配了一个包含单个NSString实例变量的简单类,我应该在dealloc中释放它,还是在释放包含实例时释放它?是的,在设置实例变量时应该保留它,在不再需要时释放它。我有一篇博客文章,上面有一组指向内存管理文章的链接:谢谢你,格雷厄姆,我想我现在就到了,我已经链接了你的博客文章,供将来参考。周末愉快。很可能,您看到的没有显式保留解码对象的代码示例正在使用setter方法声明所有权。