Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 实施-init与&x2B;初始化_Objective C_Initialization_Init - Fatal编程技术网

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