【发布时间】:2013-01-01 12:21:41
【问题描述】:
我有一个+initialize 方法被多次调用,但我不明白为什么。
根据文档,它将为每个类(以及子类)调用一次,
这是我正在使用的代码:
@interface MyClass : NSObject
@end
static NSArray *myStaticArray;
@implementation MyClass
+ (void)initialize
{
myStaticArray = [NSArray array];
}
@end
(显然还有其他代码,但这是相关部分)。
MyClass 没有子类。它没有做任何花哨的事情。 +initialize 在我的应用程序启动时被调用一次(NSApplication 的委托告诉它用磁盘中的数据填充 myStaticArray)。然后第二次调用 +initialize,即用户第一次选择与此类相关的菜单项。
我只是在我的initialize 代码周围添加了dispatch_once(),这显然解决了我的问题。但我不明白这是怎么回事?为什么在没有子类的情况下会多次调用?
这是第一次调用 +initialize 时的堆栈跟踪:
+[MyClass initialize]
_class_initialize
objc_msgSend
-[MyAppDelegate applicationDidBecomeActive:]
_CFXNotificationPost
NSApplicationMain
main
start
这是第二次调用:
+[MyClass initialize]
_class_initialize
NSApplicationMain
main
start
如您所见,我的代码似乎没有触发对 +initialize 的第二次调用(堆栈跟踪中没有任何内容)。它立即发生之后我显示一个窗口,该窗口显示由+initialize 清除的静态数组的内容(窗口显示数组内容,但紧接着数组为空)。
【问题讨论】:
-
您可以添加
NSLog(@"class=%@", NSStringFromClass([self class]));并发布输出。 -
@trojanfoe 谢谢,我应该早点尝试。第二次是由
NSKVONotifying_MyClass触发的,直到现在我才听说过。似乎KVO自动创建了某些对象的子类?我有一个NSTableView显示这个类的一些对象(通过NSArrayController)。有人知道更多吗?我找不到太多文档。 -
讨论了动态创建的子类here,但这不是实际文档。无论如何,希望它有所帮助。
-
@bbum 来源是 Key Value Observing。我有一个绑定到数组控制器的表视图,该控制器绑定到包含此类对象的数组。堆栈跟踪中没有任何用处,它在
NSApplicationMain()内部,但在 self 上执行 NSLog 会显示类名:NSKVONotifying_MyClass。在我展示包含表格视图的窗口后不久它就会被调用(不是展示它的一部分。在那之后)。
标签: objective-c cocoa