initialize 和 init 得区别

Objective-C中带有运行时间的好处是,它可以在你的程序运行的流程中进行参与。在Objective-C中,它包括检查是否一个对象可以处理特定的消息,如果不能处理,它就帮助你自动调用其他特定的方法去完成。

initialize不是init

运行时间的行为之一就是initialize。虽然看起来有点像大家常见的init,但是他们并不相同。

在程序运行过程中,它会在你程序中每个类调用一次initialize。这个调用的时间发生在你的类接收到消息之前,但是在它的超类接收到initialize之后。

举例:

Duck.h

#import <Foundation/Foundation.h>

 

@interface Duck : NSObject

 

@end

 

Duck.m

#import "Duck.h"

 

@implementation Duck

 

+ (void)initialize

{

    NSLog(@"I'm %@ initialize!" ,[self class]);

}

 

- (instancetype)init

{

    if (self = [super init])

    {

        NSLog(@"I,m Duck init!");

    }

    

    return self;

}

@end

测试:

  Duck *duck1 = [[Duck alloc] init];

    Duck *duck2 = [[Duck alloc] init];

    Duck *duck3 = [[Duck alloc] init];

 

结果:

2016-04-12 15:49:43.747 InitializeAndInt[9444:748335] I'm Duck initialize!

2016-04-12 15:49:43.748 InitializeAndInt[9444:748335] I,m Duck init!

2016-04-12 15:49:43.748 InitializeAndInt[9444:748335] I,m Duck init!

2016-04-12 15:49:43.748 InitializeAndInt[9444:748335] I,m Duck init!

我们可以看到,虽然我们创建了3个Duck的实例,但是initialize仅仅被调用了一次。我们也可以看到,直到我们创建了一个Duck的实例,initialize才被调用。

 

但是如果Duck有一个子类的话,比如我们建一个Duck的子类叫做Chicken

Chicken.h

#import "Duck.h"

 

@interface Chicken : Duck

 

@end

 Chicken.m

#import "Chicken.h"

 

@implementation Chicken

 

 

@end

 

结果:

2016-04-12 15:54:09.160 InitializeAndInt[9517:750847] I'm Duck initialize!

2016-04-12 15:54:09.161 InitializeAndInt[9517:750847] I,m Duck init!

2016-04-12 15:54:09.161 InitializeAndInt[9517:750847] I,m Duck init!

2016-04-12 15:54:09.161 InitializeAndInt[9517:750847] I,m Duck init!

2016-04-12 15:54:09.161 InitializeAndInt[9517:750847] I'm Chicken initialize!

2016-04-12 15:54:09.161 InitializeAndInt[9517:750847] I,m Duck init!

我们看到了4个Duck的init和2个Duck的initialize方法。这是怎么回事呢?

看来如果一个子类没有实现initialize方法,那么超类会调用这个方法两次,一次为自己,而一次为子类。

 

 

posted @ 2016-04-12 11:35  平凡得脚步  阅读(1356)  评论(0编辑  收藏  举报