-init与+ initialize的实现 [英] Implementation of -init vs. +initialize

查看:130
本文介绍了-init与+ initialize的实现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

谁能解释为什么我们需要在+initialize方法中包含if (self == SomeClass class)吗?

Can anyone explain why we need to include if (self == SomeClass class) inside the +initialize method?

我发现了类似的问题(在下面列出),但是没有任何具体说明:

I’ve found similar questions (listed below), but didn’t find any specific clarifications:

  1. Objective-C:初始化与初始化
  2. 应该+ initialize/+加载始终以以下条件开始:if(self == [MyClass class])守卫?
  1. Objective-C: init vs initialize
  2. Should +initialize/+load always start with an: if (self == [MyClass class]) guard?

每个人都说,如果您没有在子类中实现/覆盖+initialize,那么它将两次调用父类.

Everyone says that if you don’t implement/override +initialize in Subclass, then it’s going to call the parent class twice.

任何人都可以特别解释该部分,特别是为什么它两次调用父类?

Can anyone explain that part in particular, specifically why does it call the parent class twice?

最后,为什么当我们在继承自NSObject的类中实现+initialize时却没有发生,我们在其中创建了一个自定义的-init方法并调用self = [super init];.

Lastly, why doesn’t it happen when we implement +initialize in the class that inherits from NSObject, where we create a custom -init method and call self = [super init];.

推荐答案

-init+initialize是完全不同的东西.首先是初始化 instances ;第二个是初始化 classs .

-init and +initialize are completely different things. The first is for initializing instances; the second is for initializing classes.

第一次给任何给定类的消息时,运行时确保在其上及其超类调用+initialize.首先对超类进行初始化,因为超类需要在子类自身进行初始化之前准备好.

The first time any given class is messaged, the runtime makes sure to invoke +initialize on it and its superclasses. The superclasses are initialized first because they need to be ready before any subclass can initialize itself.

因此,第一次发送YourSubclass消息时,运行时可能会执行以下操作:

So, the first that time YourSubclass is messaged, the runtime might do something like:

[NSObject initialize];
[YourClass initialize];
[YourSubclass initialize];

(尽管这不太可能是第一次向NSObject发送消息,所以它可能此时不需要初始化.这只是为了说明.)

(Although it's very unlikely that this would be the first time that NSObject is messaged, so probably it doesn't need to be initialized at this point. It's just for illustration.)

如果YourSubclass没有实现+initialize,则上面显示的[YourSubclass initialize]调用实际上将调用+[YourClass initialize].那只是工作中的正常继承机制.这将是第二次调用+[YourClass initialize].

If YourSubclass doesn't implement +initialize, then the [YourSubclass initialize] invocation shown above will actually call +[YourClass initialize]. That's just the normal inheritance mechanism at work. That will make the second time that +[YourClass initialize] has been called.

由于在+initialize方法中完成的工作通常只是一次操作,因此必须使用防护if (self == [TheClassWhoseImplementationThisMethodIsPartOf class]).此外,该工作通常假设self指向正在编写的当前类,因此这也是需要警惕的原因.

Since the work done in a +initialize method is usually the sort of thing that should only be done once, the guard if (self == [TheClassWhoseImplementationThisMethodIsPartOf class]) is necessary. Also, that work often assumes that self refers to the current class being written, so that's also a reason for the guard.

您引用的第二个答案记录了一个例外,这是一种用+setKeys:triggerChangeNotificationsForDependentKey:方法注册KVO依赖密钥的旧机制.该方法特定于它所调用的实际类,而不是任何子类.您应该避免使用它,而应使用更现代的+keyPathsForValuesAffectingValueForKey:+keyPathsForValuesAffecting<Key>方法.如果必须使用旧方法,请将其放在防护罩之外.同样,此类的子类必须调用super,这通常是无法完成的.

The second answer you cite notes an exception, which is the old-style mechanism for registering KVO dependent keys with the +setKeys:triggerChangeNotificationsForDependentKey: method. That method is specific to the actual class it's invoked on, not any subclasses. You should avoid it and use the more modern +keyPathsForValuesAffectingValueForKey: or +keyPathsForValuesAffecting<Key> methods. If you must use the old way, put that part outside of the guard. Also, subclasses of such a class must call through to super which is not normally done.

更新:

+initialize方法通常不应调用super,因为运行时已经初始化了超类.当且仅当已知超类使用旧机制注册从属密钥时,任何子类都必须通过调用super.

A +initialize method should not normally call through to super because the runtime has already initialized the superclass. If and only if the superclass is known to register dependent keys using the old mechanism, then any subclasses must call through to super.

-init情况下,不存在相同的问题,因为运行时在调用您的方法之前不会自动为您调用超类init方法.确实,如果您的init方法没有调用super,那么将没有任何东西可以初始化实例的超类的部分".

The same worry does not exist in the case of -init because the runtime is not automatically calling the superclass init method for you before calling yours. Indeed, if your init method does not call through to super, then nothing will have initialized the superclass's "part" of the instance.

这篇关于-init与+ initialize的实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆