分类和扩展

97 阅读1分钟

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 将合并后的分类数据(方法 属性 协议)插入到类原来数据的前面

扩展

为一个类声明一些额外的方法和属性 扩展只能声明方法 属性,具体实现需要在源文件中实现