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
initializeAndLeaveLocked
initializeNonMetaClass
- i
nitializeNonMetaClass(supercls);
递归父类 -
callInitialize(cls);
((void(*)(Class, SEL))objc_msgSend)(cls, SEL_initialize);
image
-
只会调用一次
网友评论