+初始化/ +加载总是以:if(self == [MyClass class])后卫开始吗?

Tod*_*orf 10 iphone macos cocoa objective-c

在你的一个Objective-C课程中实现+ initialize或+ load方法时,你应该始终从这种防守开始吗?:

@implementation MyClass

+ (void)initialize {
    if (self == [MyClass class]) {
        ...
    }
}

...
@end
Run Code Online (Sandbox Code Playgroud)

看起来像+ load和+ initialize中的代码通常只想执行一次.所以这有助于避免子类加载/初始化时的重复执行.

我想我只是想从一些ObjC巫师那里得到一些强化,这是必要/常见的做法......

这是什么常见的智慧?你会建议总是这样做吗?

对于+ load和+ initialize,你的建议是否相同,或者它们应该如何处理?

谢谢.

e.J*_*mes 5

快速回答是:没有.

这件事情深入的讨论可以在苹果开发者邮件列表上找到.

它的要点是:

  1. +initialize在对子类调用之前,运行时实际上会调用超类.
  2. 如果确实包含了防护,那么具有自己+initialize方法的类的子类将不会触发相关的KVO通知.

有关第2点的示例,请务必阅读上述主题中的这篇文章.

  • 在`+ initialize`中完成的绝大多数事情应该只进行一次,并且只针对实现它的类,而不是子类.旧的KVO依赖键机制是一个值得注意的重要例外,它应该在这样的保护之外完成,但是在大多数其他情况下应该使用保护.引用的电子邮件主题主要是关于`+ initialize`是否应该调用`super`,它不应该. (2认同)

Mat*_*her 4

是的,如果您要初始化只应初始化一次的全局变量,则应该在初始化和加载方法中执行此操作。

也就是说,在很多情况下你可以避免它......

如果需要对每个类的每个继承者执行工作,则不应使用此条件换行:

  • 例如,将每个类的所有继承类名添加到一个集合中。
  • 编辑添加:或者您正在建立 KVO 依赖关系(如 eJames 提到的)

还有一些情况你不需要费心:

  • 如果您执行的操作是幂等的(如果重复则不要更改值)
  • 该类是“密封的”(设计上没有后代)

“幂等”部分是相关的。初始化程序应该只是设置初始状态(每次都应该相同)。在一个好的初始化器中,重复应该不重要。尽管我认为如果您忘记在确实重要时将方法包装在条件中,这可能会很烦人。

编辑补充:正​​确反映任何仅初始化一次要求的不同方法是测试要初始化的属性是否已初始化。IE

id myGlobalObject = nil;

+(void)initialize
{
    if (myGlobalObject == nil)
    {
        myGlobalObject = [[MyGlobalClass alloc] init];
    }
}
Run Code Online (Sandbox Code Playgroud)