Objective c 实施-init与&x2B;初始化
有人能解释为什么我们需要在Objective c 实施-init与&x2B;初始化,objective-c,initialization,init,Objective C,Initialization,Init,有人能解释为什么我们需要在+initialize方法中包含if(self==SomeClass) 我发现了类似的问题(如下所列),但没有找到任何具体的澄清: 每个人都说,如果不在子类中实现/重写+初始化,那么它将调用父类两次 有谁能特别解释一下这一部分,特别是为什么它两次调用父类 最后,当我们在继承自NSObject的类中实现+initialize时,为什么不会发生这种情况,在这个类中,我们创建了一个自定义的-init方法并调用self=[super init]您所引用的问题有很好的公认答案
+initialize
方法中包含if(self==SomeClass)
我发现了类似的问题(如下所列),但没有找到任何具体的澄清:
每个人都说,如果不在子类中实现/重写+初始化,那么它将调用父类两次
有谁能特别解释一下这一部分,特别是为什么它两次调用父类
最后,当我们在继承自NSObject的类中实现+initialize
时,为什么不会发生这种情况,在这个类中,我们创建了一个自定义的-init
方法并调用self=[super init]代码>您所引用的问题有很好的公认答案。总之,+initialize
由运行时在每个类上调用,因此对于具有N个子类的超类,它将在超类上被调用N+1次(直接调用一次,继承它的每个子类调用一次)。如果一个子类重写它并调用super,情况也是如此
您可以通过在超类级别上询问“这是由系统直接初始化的,而不是由我的子类继承或调用的‘super’”来对此进行防御
-init
用于初始化类的实例,默认情况下运行时不会像+initialize
那样调用它。实例继承它们的-init实现,可以覆盖继承的实现,还可以通过调用[super init]享受继承实现的好处代码>和初始化是完全不同的事情。第一个用于初始化实例;第二个是初始化类
第一次向任何给定类发送消息时,运行库确保对其及其超类调用+initialize
。超类首先被初始化,因为它们需要在任何子类初始化自身之前准备好
因此,当YourSubclass
第一次收到消息时,运行时可能会执行以下操作:
[NSObject initialize];
[YourClass initialize];
[YourSubclass initialize];
(虽然这不太可能是第一次向NSObject
发送消息,所以此时可能不需要对其进行初始化。这只是为了说明。)
如果您的子类
没有实现+初始化
,那么上面显示的[您的子类初始化]
调用实际上将调用+[您的类初始化]
。这只是正常的继承机制在起作用。这将是第二次调用+[YourClass initialize]
由于在+initialize
方法中完成的工作通常是只应执行一次的,因此需要使用(self==[实现此方法的类是类的一部分的类])的警卫。此外,该工作通常假定self
引用当前正在编写的类,因此这也是保护的原因之一
您引用的第二个答案指出了一个例外,即使用+setKeys:triggerchangenotificationsforderependentkey:
方法注册依赖KVO的密钥的旧式机制。该方法特定于调用它的实际类,而不是任何子类。您应该避免使用它,并使用更现代的+keypathsforvaluesafectingvalueforkey:
或+keypathsforvaluesafecting
方法。如果你必须用老办法,把那部分放在防护罩外面。此外,此类类的子类必须调用super
,这通常是不需要的
更新:
+initialize
方法通常不应该调用super
,因为运行时已经初始化了超类。如果且仅当已知超类使用旧机制注册依赖密钥时,则任何子类都必须调用super
在-init
的情况下不存在同样的担忧,因为运行时在调用您的方法之前不会自动为您调用超类init方法。实际上,如果您的init方法没有调用super,那么就不会初始化超类实例的“部分”。假设您有一个实现了+初始化的超类和一个没有实现的子类
@interface SuperClass : NSObject @end
@implementation SuperClass
+(void)initialize {
NSLog(@"This is class %@ running SuperClass +initialize", self);
}
@end
@interface SubClass : SuperClass @end
@implementation SubClass
// no +initialize implementation
@end
使用超类。这会引发对+[SuperClass initialize]
的调用
[SuperClass class];
=> This is class SuperClass running SuperClass +initialize
现在使用子类。运行时在子类
中查找+initialize
的实现,但未找到任何内容。然后在超类中查找继承的实现并找到它。继承的实现即使已代表超类本身调用过一次,也会被调用:
[SubClass class];
=> This is class SubClass running SuperClass +initialize
防护装置允许您执行最多只能运行一次的工作。对+initialize
的任何后续调用都有一个不同的类作为self
,因此警卫可以忽略它们。init和initialize彼此无关。@rmaddy Inside-init
您有self=[super init]
调用父级的+初始化
,还是我不正确?您不正确。在调用任何其他类或实例方法之前,每个类调用一次initialize。@rmaddy这就是为什么我想知道并要求澄清的原因。什么时候打电话?如果我不包含if语句,它怎么会被调用两次呢?因此,在任何情况下,+initialize
都会被运行时调用,而用户没有代码?如果是,我想知道在什么情况下会在子类内部调用super上的+initialize
。@danh,不仅当子类调用super
时,该方法才会被调用两次。这也是当子类没有实现+initialize
时,这是目前最常见的情况
[SubClass class];
=> This is class SubClass running SuperClass +initialize