引言
- 通过上文OC类的加载上知道加载类的时候会受到
load
方法的影响,加上分类的load
方法,会出现下面四种情况
- 1,非懒加载类和非懒加载分类
- 2,懒加载类和非懒加载分类
- 3,懒加载类和懒加载分类
- 4,非懒加载类和懒加载分类
分类的本质
- 创建一个Person的分类Test,新增一个age属性,增加一个run方法,通过
clang
编译为cpp文件,可以看到分类的本质是一个结构体
struct _category_t {
const char *name;
struct _class_t *cls;
const struct _method_list_t *instance_methods;
const struct _method_list_t *class_methods;
const struct _protocol_list_t *protocols;
const struct _prop_list_t *properties;
};
- 它里面有分类的名字,主类,实例方法列表,类方法列表,协议列表,属性列表,比较特殊的是它没有存储成员变量的数据,在分类中增加属性,只会生成一个set、get方法的声明
- 查看方法列表,因为我在.m文件里实现了set、和get方法
static struct /*_method_list_t*/ {
unsigned int entsize; // sizeof(struct _objc_method)
unsigned int method_count;
struct _objc_method method_list[3];
} _OBJC_$_CATEGORY_INSTANCE_METHODS_Person_$_Test __attribute__ ((used, section ("__DATA,__objc_const"))) = {
sizeof(_objc_method),
3,
{{(struct objc_selector *)"setAge:", "v20@0:8i16", (void *)_I_Person_Test_setAge_},
{(struct objc_selector *)"age", "i16@0:8", (void *)_I_Person_Test_age},
{(struct objc_selector *)"run", "v16@0:8", (void *)_I_Person_Test_run}}
};
- 我们也可以通过
Developer Documentation
搜索Category
查看分类的结构
- 还可以直接通过objc源码搜索
category_t
非懒加载类和非懒加载分类
- 通过前面的分析,我们知道只要实现了
load
方法就可以让类或者分类变为非懒加载的类或者分类
- 类的加载
map_images
->map_images_nolock
->_read_images
->_getObjc2NonlazyClassList
->realizeClassWithoutSwift
->methodizeClass
->attachToClass
->load_images
-
load_images
里面开始加载分类,loadAllCategories
->load_categories_nolock
->attachCategories
懒加载类和非懒加载分类
- 我们实现了两个分类,在Test分类里面没有实现
load
,另外一个分类没有实现load
- 类的加载
load_images
->prepare_load_methods
->realizeClassWithoutSwift
->methodizeClass
->attachToClass
通过断点调试发现,没有实现load
方法的分类会通过直接读取Mach-O的数据到data(),然后在attachToClass
里面实现了attachCategories
加载分类的方法。
懒加载类和懒加载分类
- 类的加载会在第一次给类发送信息的时候,
lookUpImpOrForward
->initializeAndLeaveLocked
->initializeAndMaybeRelock
->realizeClassMaybeSwiftAndUnlock
->realizeClassWithoutSwift
->methodizeClass
->attachToClass
- 分类的数据在编译的时期就加入到Mach-O文件中。
非懒加载类和懒加载分类
- 类的加载
map_images
->map_images_nolock
->_read_images
->_getObjc2NonlazyClassList
->realizeClassWithoutSwift
->methodizeClass
->attachToClass
->load_images
- 分类的数据在编译的时期就加入到Mach-O文件中。
网友评论