简体   繁体   English

+ initialize被调用不止一次

[英]+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.

相关问题 awakeFromNib调用了不止一次 - awakeFromNib called more than once 如何使viewDidLoad多次调用 - How to make viewDidLoad called more than once Objective-C初始化(静态方法)被称为更多一次? - Objective-C initialize (static method) called more that once? initWithImage可以正常工作initWithFrame被多次调用 - initWithImage works fine initWithFrame is being called more than once 在UITabBarController中是否多次调用viewDidLoad? - Does viewDidLoad get called more than once in UITabBarController? 如何防止collectionView:didSelectItemAtIndexPath委托方法多次调用 - How to prevent collectionView:didSelectItemAtIndexPath delegate method called more than once NSRegularExpression:enumerateMatchesInString在多次调用时挂起 - NSRegularExpression:enumerateMatchesInString hangs when called more than once iOS 8后台获取从未在设备上多次调用 - ios 8 Background fetch is never called on device more than once time application:didReceiveRemoteNotification:fetchCompletionHandler:多次调用。如何避免? - application: didReceiveRemoteNotification: fetchCompletionHandler: called more than once.How to avoid? 为什么在拖动视图时多次调用touchesMoved方法-iOS - Why is the touchesMoved method not being called more than once when a view is being dragged--IOS
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM