+ initialize被调用不止一次

Abh*_*ert 10 cocoa objective-c

我有一个+initialize被多次调用的方法,我不明白为什么.

根据文档,它将为每个类(以及子类)调用一次,

这是我正在使用的代码:

@interface MyClass : NSObject

@end

static NSArray *myStaticArray;

@implementation MyClass

+ (void)initialize
{
  myStaticArray = [NSArray array];
}

@end
Run Code Online (Sandbox Code Playgroud)

(显然还有其他代码,但这是相关部分).

没有子类MyClass.它没有任何花哨的东西.当我的应用程序启动时,+ initialize被调用一次(NSApplication的委托告诉它用磁盘中的数据填充myStaticArray).然后第二次调用+ initialize,这是用户第一次选择与此类相关的菜单项.

我只是添加dispatch_once()了我的initialize代码,这显然解决了我的问题.但我不明白发生了什么事?当没有子类时,为什么会多次调用它?

这是第一次调用初始化时的堆栈跟踪:

+[MyClass initialize]
_class_initialize
objc_msgSend
-[MyAppDelegate applicationDidBecomeActive:]
_CFXNotificationPost
NSApplicationMain
main
start
Run Code Online (Sandbox Code Playgroud)

这是第二个电话:

+[MyClass initialize]
_class_initialize
NSApplicationMain
main
start
Run Code Online (Sandbox Code Playgroud)

如您所见,我的代码似乎没有触发第二次调用+ initialize(堆栈跟踪中没有任何内容).它我显示一个窗口立即出现,+initialize该窗口显示清除的静态数组的内容(窗口显示数组内容,但在此之后数组为空).

bbu*_*bum 24

+initialize将在第一次引用时(通过消息)发送给每个类,包括动态创建的类.运行时没有保护措施防止多次触发执行.如果子类已初始化但未实现+initialize,super则链中的任何内容都将再次调用它们.

正交地,通过创建被观察实例的类的动态派生子类来实现自动KVO.该子类+initialize就像任何其他类一样,从而触发父类的多次执行+initialize.

运行时可以采取措施来防止这种情况.但是,由于+initialize一直被记录为可能被执行多次,这增加了复杂性(考虑到KVO课程频繁来来去去,这是非常复杂的)并不值得付出努力.

目前推荐的模式是:

+ (void) initialize
{
      static dispatch_once_t once;
      dispatch_once(&once, ^{
        ... one time initialization here ...
      });
}
Run Code Online (Sandbox Code Playgroud)