The load
message
运行时发送load
在类对象加载到进程的地址空间后不久,向每个类对象发送消息。对于属于程序可执行文件一部分的类,运行时会发送load
在进程生命周期的早期就发出消息。对于共享(动态加载)库中的类,运行时会在共享库加载到进程的地址空间后立即发送加载消息。
此外,运行时仅发送load
到一个类对象,如果该类对象本身实现了load
方法。例子:
@interface Superclass : NSObject
@end
@interface Subclass : Superclass
@end
@implementation Superclass
+ (void)load {
NSLog(@"in Superclass load");
}
@end
@implementation Subclass
// ... load not implemented in this class
@end
运行时发送load
消息给Superclass
类对象。确实如此not发送load
消息给Subclass
类对象,尽管Subclass
继承该方法Superclass
.
运行时发送load
发送消息后向类对象发送消息load
发送给该类的所有超类对象的消息(如果这些超类对象实现了load
) 以及您链接到的共享库中的所有类对象。但你不知道你自己的可执行文件中的哪些其他类已收到load
yet.
您的进程加载到其地址空间的每个类都会收到一个load
消息,如果它实现了load
方法,无论您的进程是否使用该类的任何其他用途。
您可以看到运行时如何查找load
方法作为特殊情况_class_getLoadMethod
of objc-runtime-new.mm,并直接从call_class_loads
in objc-loadmethod.mm.
运行时还运行load
它加载的每个类别的方法,即使同一类上的多个类别实现load
。这很不寻常。通常,如果两个类别在同一个类上定义了相同的方法,则其中一个方法将“获胜”并被使用,而另一个方法将永远不会被调用。
The initialize
Method
运行时调用initialize
发送第一条消息之前类对象上的方法(除了load
or initialize
) 到类对象或类的任何实例。该消息是使用正常机制发送的,因此如果您的类没有实现initialize
,但是从一个这样做的类继承,那么你的类将使用其超类的initialize
。运行时将发送initialize
首先发送给一个类的所有超类(如果超类尚未发送)initialize
).
Example:
@interface Superclass : NSObject
@end
@interface Subclass : Superclass
@end
@implementation Superclass
+ (void)initialize {
NSLog(@"in Superclass initialize; self = %@", self);
}
@end
@implementation Subclass
// ... initialize not implemented in this class
@end
int main(int argc, char *argv[]) {
@autoreleasepool {
Subclass *object = [[Subclass alloc] init];
}
return 0;
}
该程序打印两行输出:
2012-11-10 16:18:38.984 testApp[7498:c07] in Superclass initialize; self = Superclass
2012-11-10 16:18:38.987 testApp[7498:c07] in Superclass initialize; self = Subclass
由于系统发送initialize
方法惰性地,除非您的程序实际将消息发送到类(或子类,或类或子类的实例),否则类不会接收消息。当你收到时initialize
,你的进程中的每个类都应该已经收到load
(如果合适的话)。
规范的实现方式initialize
这是:
@implementation Someclass
+ (void)initialize {
if (self == [Someclass class]) {
// do whatever
}
}
这种模式的要点是避免Someclass
当它有一个未实现的子类时重新初始化自身initialize
.
运行时发送initialize
消息在_class_initialize
函数于objc-initialize.mm。你可以看到它使用了objc_msgSend
发送,这是正常的消息发送功能。
进一步阅读
查看迈克·阿什的周五问答关于这个话题。