
TOC
load_images 分析
(补)load在什么时候调用
在 load_images 里面调用
怎么调用?
typedef void(*load_method_t)(id, SEL);
(*load_method)(cls, SEL_load);
- 能拿到
prepare中保存的数据模型有id和SEL - 在call的地方拿到这两个方法
直接调用函数IMP - 而
不需要调用msg_send发送消息
(面试)主类和分类的方法怎么调用
1. load 方法
- 先主类后分类:
call_load_methods方法中先调用主类的load方法,然后再调用分类的load方法 - 多个分类取决于
Compile Sources中的顺序
2. 一般方法
- 只调用分类方法:分类方法被
attachlist往前面插,所以会调用分类方法- 在方法查找的时候找到了分类中的方法便不再继续查找了,所以造成分类覆盖主类方法的假象
- 实际上并没有方法覆盖这个说法
prepare_load_methods 准备load方法
1. 准备load方法
- 将
类的load方法存入loadable_classes数组中 - 将
分类的load方法存入loadable_categories数组中
2. 取出所有加载进去的类列表
classref_t *classlist = _getObjc2NonlazyClassList(mhdr, &count);
3. 递归加载load方法
递归:
schedule_class_load递归父类:
schedule_class_load(cls->superclass);-
把这个类的
load方法加到list中:add_class_to_loadable_list(cls);loadable_classes[loadable_classes_used].cls = cls; loadable_classes[loadable_classes_used].method = method;
4. 取出分类数据
category_t **categorylist = _getObjc2NonlazyCategoryList(mhdr, &count);
- 先确保类已经初始化了:realizeClassWithoutSwift(cls);
- 加载分类中的load方法到list中:
add_category_to_loadable_list(cat);loadable_categories[loadable_categories_used].cat = cat; loadable_categories[loadable_categories_used].method = method;
call_load_methods 调用 load 方法
- 压栈自动释放池:
objc_autoreleasePoolPush(); - 调用主类的 load 方法:
call_class_loads();。调用方式:(*load_method)(cls, SEL_load); - 调用分类的 load 方法:
call_category_loads();。调用方式:(*load_method)(cls, SEL_load); - 出栈:
objc_autoreleasePoolPop(pool);
(补)dealloc 方法调用顺序
这里做一个简单的介绍,后面会详细讲
_objc_rootDealloc(self);obj->rootDealloc();object_dispose((id)this);-
objc_destructInstance(obj);if (obj->hasCxxDtor();) object_cxxDestruct(obj); object_cxxDestructFromClass(obj, obj->ISA()); if (obj->hasAssociatedObjects();) _object_remove_assocations(obj); elements.push_back(j->second); 拷贝所有要移除的关联 associations.erase(i); 移除辅助表
initalize 分析
-
alloc/class
initializeAndLeaveLockedinitializeNonMetaClass- i
nitializeNonMetaClass(supercls);递归父类 -
callInitialize(cls);
((void(*)(Class, SEL))objc_msgSend)(cls, SEL_initialize);
image
只会调用一次

image
