objective-c - 在 init 和 dealloc 方法中有效使用访问器?

标签 objective-c properties initialization accessor dealloc

我现在从多个来源(stackoverflow.com、cocoa-dev、文档、博客等)听说在 init 和 dealloc 方法中使用访问器和设置(foo、setFoo:) 是“错误的” .我知道如果您这样做,很可能会混淆正在观察该属性的其他对象。 (给出了一个简单的例子here)

但是,我不得不说,我不赞同这种做法,原因如下:

新的 Objective-C 运行时(iPhone 上的运行时和 10.5 中的 64 位运行时)允许您声明属性而不声明相应的 ivar。例如,以下类将在 10.5 或 iPhone(设备,而非模拟器)上编译得很好:

@interface Foo : NSObject { }

  @property (retain) id someObject;

@end

@implementation Foo

  @synthesize someObject;

@end

了解以上是一个完全有效的 Objective-C 类,假设我决定编写一个初始化程序,并出于内存管理目的,编写一个 dealloc 方法(因为 GC 在 iPhone 上不可用)。我读过的关于初始化器和释放的所有内容都会引导我编写以下两个方法:

- (id) init {
  if (self = [super init]) {
    //initialize the value of someObject to nil
    [self setSomeObject:nil];
  }
  return self;
}

- (void) dealloc {
  //setting someObject to nil will release the previous value
  [self setSomeObject:nil];
  [super dealloc];
}

但是,根据文档和流行观点,这是“错误的”。所以我的问题是:

  1. 我应该如何在不使用访问器的情况下初始化 someObject?您可能会说编译器(或运行时或其他)将确保 someObject 已设置为 nil,但我认为依赖它是不正确的行为。我有良好的 C 语言背景,见过很多由于未正确初始化变量而导致的错误,这似乎没什么不同。
  2. 如果我不应该在 dealloc 方法中使用访问器,我该如何释放 someObject?

如果其中任何一个的答案是“你不能”,那么在你的 init 和 dealloc 方法中使用访问器有什么不好呢?

最佳答案

编辑(2013 年 2 月 13 日): 正如我在下面的评论中所指出的,特别是自从添加 ARC 以来,我改变了我的想法。在 ARC 之前,由于 init 中不正确的 ivar 分配,我看到了很多导致崩溃的错误。 IMO,尤其是与初级团队合作时,在 init 中使用访问器的罕见问题被 ivar 访问的常见错误所抵消。由于 ARC 已经消除了这些类型的错误,在 init 中使用访问器可能导致的罕见但可能的错误更为重要,因此我转而支持在 中直接使用 ivars >initdealloc,并且只在那些地方;其他任何可能的访问器(显然你不能在访问器本身内部使用访问器....)


ARC 前答案

我强烈反对那些反对在 -init 中使用访问器的人。在几乎所有情况下,这是一个使用访问器的好地方,它避免了很多我在新 Cocoa 编码器中看到的错误,这些编码器在 -init 中分配时总是无法保留。

-dealloc 是一个更艰难的决定。我很自然地倾向于在那里使用访问器(这样它们就可以在任何地方使用),但是由于 KVO(或者如果你在你的 setter 中发布更改通知,甚至是 NSNotifications),它可能会导致头痛。也就是说,虽然我不在 -dealloc 中使用访问器,但我认为它非常值得商榷,Apple 对此非常不一致(我们知道他们在调用 setView:例如 UIViewController 的 -dealloc)。

无论如何,我会说访问器使用不足导致的错误是过度使用的 100 倍。除非有充分的理由不这样做,否则我总是会错误地使用它们。

关于objective-c - 在 init 和 dealloc 方法中有效使用访问器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1283419/

相关文章:

spring - 构建后、部署前的属性文件配置

c++ - 如何将值初始化为 vector 中声明的对象?

c++ - return 语句后跟初始化列表

objective-c - NSRemoteView 在日志中生成一条奇怪的消息

iphone - 如何为应用程序商店起一个长名称,然后在图标下起一个短名称?

c#:将 Get/Set 从 vb.net 转换为 c#

PHP:封装的目的是什么?

ios - 如何使用 UIView 框架创建自定义初始化

ios - 需要在 UILabel 的文本中获取多个@符号的 NSRanges 及其后面的文本

objective-c - addSubView 上令人讨厌的 iOS SIGABRT 错误 - 即使在以前工作的旧快照和备份版本上也是如此?