Objective-C中是带有运行时间的。spa
运行时间好处是,它能够在你的程序运行的流程中进行参与。在Objective-C中,它包括检查是否一个对象能够处理特定的消息,若是不能处理,它就帮助你自动调用其余特定的方法去完成。.net
initialize不是init对象
运行时间的行为之一就是initialize。虽然看起来有点像你们常见的init,可是他们并不相同。get
在程序运行过程当中,它会在你程序中每一个类调用一次initialize。这个调用的时间发生在你的类接收到消息以前,可是在它的超类接收到initialize以后。it
举个例子,好比一个叫作Duck的类:io
#import "Duck.h";
@implementation Duck
+(void) initialize {
NSLog(@"Duck initialize");
}
-(void) init {
NSLog(@"Duck init");
}
@end class
咱们在这里记录initialize和init调用的时间。import
咱们创建三个Duck对象的实例:程序
NSLog(@"Hello, World!");方法
Duck* duck1 = [[Duck alloc] init];
Duck* duck2 = [[Duck alloc] init];
Duck* duck3 = [[Duck alloc] init];
看一下记录:
[Session started at 2008-03-23 20:03:25 -0400.]
2016-02-27 20:03:25.869 initialize_example[30253:10b] Hello, World!
2016-02-27 20:03:25.871 initialize_example[30253:10b] Duck initialize
2016-02-27 20:03:25.872 initialize_example[30253:10b] Duck init
2016-02-27 20:03:25.873 initialize_example[30253:10b] Duck init
2016-02-27 20:03:25.873 initialize_example[30253:10b] Duck init
咱们能够看到,虽然咱们建立了3个Duck的实例,可是initialize仅仅被调用了一次。咱们也能够看到,直到咱们建立了一个Duck的实例,initialize才被调用。
可是若是Duck有一个子类的话,好比咱们建一个Duck的子类叫作Chicken
#import <cocoa/Cocoa.h>
#import "Duck.h"
@interface Chicken : Duck {
}
@end
注意Chicken这个类并无实现initialize方法。
若是咱们一样运行这个程序,可是加上一个Chicken的实例:
NSLog(@"Hello, World!");
Duck* duck1 = [[Duck alloc] init];
Duck* duck2 = [[Duck alloc] init];
Duck* duck3 = [[Duck alloc] init];
Chicken* chicken = [[Chicken alloc] init];
咱们期待看到4个Duck的init调用(由于咱们创建了3个Duck和一个Chicken),可是咱们看到了这样状况:
[Session started at 2016-02-27 20:13:34 -0400.]
2016-02-27 20:13:34.696 initialize_example[30408:10b] Hello, World!
2016-02-27 20:13:34.698 initialize_example[30408:10b] Duck initialize
2016-02-27 20:13:34.699 initialize_example[30408:10b] Duck init
2016-02-27 20:13:34.700 initialize_example[30408:10b] Duck init
2016-02-27 20:13:34.700 initialize_example[30408:10b] Duck init
2016-02-27 20:13:34.700 initialize_example[30408:10b] Duck initialize
2016-02-27 20:13:34.701 initialize_example[30408:10b] Duck init
咱们看到了4个Duck的init和2个Duck的initialize方法。这是怎么回事呢?
看来若是一个子类没有实现initialize方法,那么超类会调用这个方法两次,一次为本身,而一次为子类。
咱们在Duck的initialize类中记录一下类名,这样能够看得更清楚:
+(void) initialize {
NSLog(@"Duck initialize class:%@",[self class]);
}
如今看明白了:
[Session started at 2016-02-27 20:21:08 -0400.]
2016-02-27 20:21:08.816 initialize_example[30513:10b] Hello, World!
2016-02-27 20:21:08.818 initialize_example[30513:10b] Duck initialize class:Duck
2016-02-27 20:21:08.819 initialize_example[30513:10b] Duck init
2016-02-27 20:21:08.820 initialize_example[30513:10b] Duck init
2016-02-27 20:21:08.820 initialize_example[30513:10b] Duck init
2016-02-27 20:21:08.820 initialize_example[30513:10b] Duck initialize class:Chicken
2016-02-27 20:21:08.821 initialize_example[30513:10b] Duck init
若是你但愿肯定只用了initialize一次用来实现某些单独运行的工做,或者但愿实现仅仅运行一次的方法,检查一下[self class],才能肯定是不是你但愿作到的效果。