gpt4 book ai didi

objective-c - +初始化调用不止一次

转载 作者:太空狗 更新时间:2023-10-30 03:25:09 27 4
gpt4 key购买 nike

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

根据文档,它会为每个类(和子类)调用一次,

这是我正在使用的代码:

@interface MyClass : NSObject

@end

static NSArray *myStaticArray;

@implementation MyClass

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

@end

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

MyClass 没有子类。它没有做任何花哨的事情。当我的应用程序启动时,+initialize 被调用一次(NSApplication 的委托(delegate)告诉它用磁盘中的数据填充 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 清除的静态数组的内容(该窗口显示数组内容,但紧接着数组为空).

最佳答案

+initialize 将在第一次引用(通过消息)时发送给每个类,包括动态创建的类。运行时没有针对多次触发执行的保护。如果一个子类被初始化,但没有实现 +initialize,链上的任何 super 都会再次调用它们。

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

运行时可以采取措施防止这种情况发生。然而,由于 +initialize 一直被记录为可能被多次执行,因此增加的复杂性(它非常复杂,考虑到 KVO 类来来去去很频繁,潜在地)被认为是不值得的努力。

目前推荐的模式是:

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

关于objective-c - +初始化调用不止一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14110396/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com