1. +load的调用发生在程序的很早期:
1.1 C++ static initializers in your app (or framework or plugin) won't have run yet;
1.2
frameworks you link to are guaranteed to be fully loaded by this point, so it's safe to use framework classes;
1.3 Your superclasses are also guaranteed to be fully loaded,
so they are safe to use as well;
1.4 there's
no autorelease pool present at loading time (usually) so you'll need to wrap your code in one if you're calling into Objective-C stuff;
1.5
如果在main class和该class的catergory中同时实现了+load,那么这两个+load方法都会被调用。
2.
+initialize的调用发生在第一个消息发送给它所在的class时:
2.1+initialize
happens
once per class, and it happens the first time a message is sent to that class, its mechanism acts as the pseudocode below:
id objc_msgSend(id self, SEL _cmd, ...) { if(!self->class->initialized) [self->class initialize]; ...send the message... }
2.2 (?)Because +initialize
runs lazily, it's obviously not a good place
to put code to register a class that otherwise wouldn't get used.For example, NSValueTransformer or NSURLProtocol subclasses can't use +initialize
to
register themselves with their superclasses, because you set up a chicken-and-egg situation.
2.3 There's
one more trick to +initialize
. In my pseudocode above I wrote that the runtime does [self->class
. This implies that normal Objective-C dispatch semantics apply, and that if the class doesn't implement it, the superclass's
initialize]+initialize
will
run instead. That's exactly what happens. Because of this, you should always write your +initialize
method to look like this:
+ (void)initialize
{
if(self == [WhateverClass class])
{
...perform initialization...
}
}
Without that extra check, your initializations could run twice if you ever have a subclass that doesn't implement its own +initialize
method.
This is not just a theoretical concern, even if you don't write any subclasses. Apple's Key-Value Observing creates dynamic
subclasses which don't override +initialize
.
3.
以上参考自博客http://www.mikeash.com/pyblog/friday-qa-2009-05-22-objective-c-class-loading-and-initialization.html。实际测试结果:
3.1
+load的调用会引起+initialize的调用(当+initialize被实现了的时候)
3.2
某个实现了+initialize但没有实现+load的class,如果没有信息发送给它,则不会引起+initialize的调用;换句话说,如果该class实现了+load,则即使没有任何信息发送给它,+initialize也会在很早就被调用,紧接着会调用+load
3.3
subclass没有实现+initialize时,确实会引起superclass的+initialize两次调用。第一次调用是因为在调用子类的+initialize前,需要先调用父类的+initialize;第二次调用是发生在objc_msgSend函数打算调用子类的+initialize时,发现子类没有实现该方法,于是追溯到父类中,调用父类的+initialize