1 分类的注意点 分类里面可以定义@property属性,但是不会自动生成set和get方法,以及对应的成员变量
分类不能添加成员变量,但可以通过关联对象的方式添加成员变量
分类和原有类同名的方法,会优先调用分类中的方法
多个分类中同名的方法,优先调用后面参与编译的分类里面的方法
分类的底层结构
struct category_t {
const char *name;
classref_t cls;
WrappedPtr<method_list_t, PtrauthStrip> instanceMethods;
WrappedPtr<method_list_t, PtrauthStrip> classMethods;
struct protocol_list_t *protocols;
struct property_list_t *instanceProperties;
// Fields below this point are not always present on disk.
struct property_list_t *_classProperties;
method_list_t *methodsForMeta(bool isMeta) {
if (isMeta) return classMethods;
else return instanceMethods;
}
property_list_t *propertiesForMeta(bool isMeta, struct header_info *hi);
protocol_list_t *protocolsForMeta(bool isMeta) {
if (isMeta) return nullptr;
else return protocols;
}
};
分类的加载过程: 1 通过runtime 加载某个类的所有category数据
2 把所有category的方法 属性 协议数据,合并到一个大数组中,后面参与编译的category数据会在数组的前面
3 将合并后的分类数据(方法 属性 协议)插入到类原来数据的前面
扩展
为一个类声明一些额外的方法和属性 扩展只能声明方法 属性,具体实现需要在源文件中实现