[英]+initialize called more than once
I have a +initialize
method that is being called multiple times, and I don't understand why. 我有一个多次调用的
+initialize
方法,我不明白为什么。
According to the documentation, it will be called once for every class (and subclasses as well), 根据文档,它将为每个类(以及子类)调用一次,
This is the code I'm using: 这是我正在使用的代码:
@interface MyClass : NSObject
@end
static NSArray *myStaticArray;
@implementation MyClass
+ (void)initialize
{
myStaticArray = [NSArray array];
}
@end
(obviously there is other code, but that's the relevant part). (显然还有其他代码,但这是相关部分)。
There are no subclasses of MyClass
. 没有
MyClass
子类。 It doesn't do anything fancy. 它没有任何花哨的东西。 The +initialize gets called once, when my application is launched (NSApplication's delegate tells it to fill myStaticArray with data from the disk).
当我的应用程序启动时,+ initialize被调用一次(NSApplication的委托告诉它用磁盘中的数据填充myStaticArray)。 And then +initialize is called a second time, the first time a user selects a menu item that relates to this class.
然后第二次调用+ initialize,这是用户第一次选择与此类相关的菜单项。
I've simply added dispatch_once()
around my initialize
code and this obviously fixes my problem. 我只是在我的
initialize
代码周围添加了dispatch_once()
,这显然解决了我的问题。 But I don't understand what is going on? 但是我不明白发生了什么事? Why is it called more than once when there are no subclasses?
当没有子类时,为什么会多次调用它?
This is the stack trace the first time +initialize is called: 这是第一次调用初始化时的堆栈跟踪:
+[MyClass initialize]
_class_initialize
objc_msgSend
-[MyAppDelegate applicationDidBecomeActive:]
_CFXNotificationPost
NSApplicationMain
main
start
And here is the second call: 这是第二个电话:
+[MyClass initialize]
_class_initialize
NSApplicationMain
main
start
As you can see, my code does not appear to trigger the second call to +initialize (nothing in the stack trace). 如您所见,我的代码似乎没有触发第二次调用+ initialize(堆栈跟踪中没有任何内容)。 It occurs immediately after I display a window that presents the contents of the static array cleared by
+initialize
(the window shows the array contents, but immediately after that the array is empty). 它在我显示一个窗口后立即出现,该窗口显示由
+initialize
清除的静态数组的内容(窗口显示数组内容,但在此之后数组为空)。
+initialize
will be sent to each class the first time it is referenced (by message), including dynamically created classes. +initialize
将在第一次引用(通过消息)时发送到每个类,包括动态创建的类。 There is no protection in the runtime against triggering execution multiple times. 运行时没有保护措施防止多次触发执行。 If a subclass is initialized, but doesn't implement
+initialize
, whatever super
up the chain will have theirs called again. 如果一个子类被初始化,但没有实现
+initialize
,无论super
同比环比将有他们再次呼吁。
Orthogonally, automatic KVO is implemented by creating dynamically derived subclasses of the class of the observed instance. 正交地,通过创建被观察实例的类的动态派生子类来实现自动KVO。 That subclass is
+initialize
d just like any other class, thus triggering multiple executions of the parent class's +initialize
. 该子类是
+initialize
d,就像任何其他类一样,从而触发父类的+initialize
多次执行。
The runtime could take measures to protect against this. 运行时可以采取措施来防止这种情况。 However, since
+initialize
has always been documented as potentially being executed multiple times, that added complexity (it is surprisingly complex, given that KVO classes come and go quite frequently, potentially) isn't deemed worth the effort. 但是,由于
+initialize
一直被记录为可能被多次执行,这增加了复杂性(考虑到KVO类频繁出入,可能会非常复杂)并不值得付出努力。
The current recommended pattern is: 目前推荐的模式是:
+ (void) initialize
{
static dispatch_once_t once;
dispatch_once(&once, ^{
... one time initialization here ...
});
}
+initialize
gets called for each class up the inheritance chain, so if you initialise two classes that share the same superclass (or a superclass and one of its subclasses), then the superclass' +initialize
method will get called twice. 继承链为每个类调用
+initialize
,因此如果初始化两个共享同一个超类(或超类及其子类之一)的类,那么超类' +initialize
方法将被调用两次。
Could that be the reason? 这可能是原因吗?
1.Runtime called +initialize method in super class before subclass 1.Runtime在子类之前调用超类中的+ initialize方法
2.if subclass have no method then it will call parent class initialize method. 2.如果子类没有方法,那么它将调用父类初始化方法。
3.Use always chronicle way of initialize method +(void)initialize{ 3.使用始终记忆方法初始化方法+(void)initialize {
if(self==[Car Class]){
//initialize here your static var
}
}
for clear understanding read this post +(void)initialize 为了清楚理解阅读这篇文章+(void)初始化
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.