概述
+(void)load、+(void)initialize
+load | +initialize | |
---|---|---|
调用时机 | 编译时(runtime加载类和分类时 ) | 类第一次接收到消息时 |
调用方式 | 函数指针直接调用 | 消息机制msg_send |
-
+load方法
- load方法会在runtime加载类、分类时调用
- 每个类、分类+load,在程序运行过程中之调用一次
- 调用顺序
- 调用类的+load
- 按照编译先后顺序(先编译,先调用)
- 调用子类的+load之前会先调用父类的+load
- 如果父类在子类之前参与编译,先调用父类+load,子类不再调用
- 调用分类的+load
- 按照编译先后顺序(先编译,先调用)
- 调用类的+load
-
load方法源码追踪
objc-os
->_objc_init(runtime的入口)
void _objc_init(void) { // ... _dyld_objc_notify_register(&map_images, load_images, unmap_image); // load_images: }
objc-runtime-new/old
->load_images
void load_images(const char *path __unused, const struct mach_header *mh) { // ... call_load_methods(); }
objc-loadmethod
->call_load_methods
void call_load_methods(void) { // ... do { while (loadable_classes_used > 0) { call_class_loads(); } // 2. Call category +loads ONCE more_categories = call_category_loads(); } while (loadable_classes_used > 0 || more_categories); // ... }
objc-loadmethod
->call_class_loads
static void call_class_loads(void) { // ... // Call all +loads for the detached list. for (i = 0; i < used; i++) { Class cls = classes[i].cls; load_method_t load_method = (load_method_t)classes[i].method; if (!cls) continue; if (PrintLoading) { _objc_inform("LOAD: +[%s load]n", cls->nameForLogging()); } (*load_method)(cls, @selector(load)); } }
objc-loadmethod
->call_category_loads
static bool call_category_loads(void) { // Call all +loads for the detached list. for (i = 0; i < used; i++) { Category cat = cats[i].cat; load_method_t load_method = (load_method_t)cats[i].method; Class cls; if (!cat) continue; cls = _category_getClass(cat); if (cls && cls->isLoadable()) { if (PrintLoading) { _objc_inform("LOAD: +[%s(%s) load]n", cls->nameForLogging(), _category_getName(cat)); } (*load_method)(cls, @selector(load)); cats[i].cat = nil; } } }
-
+initialize 方法
- initialize方法在类第一次接收到消息时调用
- 先调用父类的initialize、在调用自己的initialize。默认每一个类只调用一次
- 如果分类实现了initialize,则会覆盖自身的initialize
- 如果自类没有实现initialize,则会调用父类的initialize。所以父类的initialize有可能调用多次
最后
以上就是糊涂月饼为你收集整理的load、initialize+(void)load、+(void)initialize的全部内容,希望文章能够帮你解决load、initialize+(void)load、+(void)initialize所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复