Category 结构 _category_t :底层用来存储分类信息的结构 struct _category_t { const char *name; //用来存放类名 struct _class_t *cls; const struct _method_list_t *instance_methods; //用来存放category里 面的实例方法列表 const struct _method_list_t *class_methods; //用来存放category里面 的类方法列表 const struct _protocol_list_t *protocols; //用来存放category里面的协议 列表 const struct _prop_list_t *properties; //用来存放category里面的属性列 }; 创建分类 CLPerson+Test 会自动生成结构体:_OBJC_$_CATEGORY_CLPerson_$_Test struct _category_t _OBJC_$_CATEGORY_CLPerson_$_Test 分类结构体中 记录着对应的 分类名称,实例方法,类方法,协议,属性 等等 创建分类的整个过程没有新的类生成,只是运行时阶段合并了方法 方法合并 两个分类实现相同方法, 并且原类也有age 和run 方法 CLPerson 实现实例方法 - age 实现类方法 + run 下面简称 age方法0 下面简称 run方法0 创建分类 CLPerson+Test 实现实例方法 - age 实现类方法 + run 下面简称 age方法1 下面简称 run方法1 CLPerson+Test2 实现实例方法 - age 实现类方法 + run 下面简称 age方法2 下面简称 run方法2 编译阶段 先编译 CLPerson+Test ,再编译 CLPerson+Test 2 编译的顺序由文件在Xcode中上下位置有关 生成对应 _category_t 变量 Runtime阶段 CLPerson 类对象实例方法列表 插入 Test 的 age 方法,再 插入Test 2 的age 方法。 更新缓存 CLPerson 的元类对象 的类方法列表,插入 run 1,run 2 实例方法 age 调用顺序 调用的是 age方法2 其它两个方法没有机会,尽管没有被覆盖 --> age2 --> age1 --> age0 --> 最后被编译的类排在前面,优先被调用 类方法run 调用 只有run 2被调用,其它不在上层的方法没有机会 --> run2 --> run1 --> run0 --> 最后被编译的类排在前面,优先被调用 如何控制分类的编译顺序? 在Build Phase->Compile Sources里面调整,直接拖拽