load
当类或分类被加载到runtime时被调用,且每个类或分类只会调用一次load方法,子类不会覆盖父类,分类不会覆盖本类;
调用顺序: 父类 > 子类 > 分类
比如有这么几个类和类别
@interface Person : NSObject
@end
@interface Person (test)
@end
@interface Student : Person
@end
@interface Student (test)
@end
@interface Student (test1)
@end
那么调用顺序是:
+[Person load]
+[Student load]
+[Student(test1) load]
+[Person(test) load]
+[Student(test) load]
- 所以先调用父类,然后调用子类,至于分类,不管是父类的分类还是子类的分类,一律由他们在Compile Sources里面出现的顺序决定,谁排在前面,谁先调用,不区分是父类的分类还是子类的分类。
initialize
在类或其子类第一次发送消息之前调用,不管是类方法还是实例方法,相当于是以懒加载的方式调用;
如果父类或父类的分类有实现initialize方法,则会先调用父类的initialize方法,再调用子类或子类的分类的initialize方法(如果子类或子类的分类有实现的话);
那么具体是调用谁的方法呢?
分类的initialize方法会覆盖本类,多个分类时后编译的分类会覆盖前面的分类,父类和子类都是以这种方式调用。
父类优先于子类,但子类不会覆盖父类,分类会覆盖本类,后编译的分类会覆盖先编译的分类。
比如上面的类,如果都有实现initialize方法
Person *p = [[Person alloc] init];
打印结果是
+[Person(test) initialize]
Student *s = [[Student alloc] init];
打印结果是
+[Person(test) initialize]
+[Student(test) initialize]