关于Category(load和initialize)

2021-05-10  本文已影响0人  love断鸿

以Person类 有5个 category为例

Catagory 本质(源码)

struct _category_t {
    const char *name;
    classref_t cls;
    struct method_list_t *instanceMethods;
    struct method_list_t *classMethods;
    struct protocol_list_t *protocols;
    struct property_list_t *instanceProperties;
    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);
};

1:Category中的实例方法和类方法存储在哪?

2: Category中的方法 和原方法 合并的时机

3: Category中的方法(属性,协议) 和原方法(属性,协议) 合并过程

4: Category和Class Extension的区别

5: Category中的+load方法

1:先调用类的+load
2:再调用分类的+load

6:普通类方法和 +load方法调用时的本质区别

7: Category中的+initialize方法

8: Category添加属性

默认情况下,因为分类底层结构的限制(category 源码里没有存储ivars的变量),不能添加成员变量到分类中。但可以通过关联对象来间接实现

使用
@interface Person (sss)
@property (nonatomic, copy) NSString *name;
@end

@implementation Person (sss)
- (void)setName:(NSString *)name {
    objc_setAssociatedObject(self, @selector(name), name, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (NSString *)name {
    return objc_getAssociatedObject(self, @selector(name));
}
@end

备注: 绑定的属性 不是存储在 Person类对象的属性列表里

关联原理
void objc_setAssociatedObject(id object, const void * key, id value ,objc_AssociationPolicy policy)
     objc_setAssociatedObject(self, @selector(name), name, OBJC_ASSOCIATION_COPY_NONATOMIC);
     objc_setAssociatedObject(参数1, 参数2, 参数3, 参数4);


AssociationsManager
AssociationsHashMap *_map;  
              ↓
     AssociationsHashMap
     disguised_ptr_t(参数1) : ObjectAssociationMap
     disguised_ptr_t(参数1) : ObjectAssociationMap....
                                     ↓
                              AssociationsMap
                              void * (参数2): ObjectAssociation
                              void * (参数2): ObjectAssociation ....
                                                       ↓
                                                ObjectAssociation
                                                    uintptr_t _policy(参数4);
                                                    id _value(参数3);
上一篇 下一篇

猜你喜欢

热点阅读