问题: Category可以添加属性吗?


Category是可以直接添加属性, 因为 category_t 是含有 propert_list_t 类型的 properties 的成员变量结构的.

但是 Category 添加属性的本质 实际上只是添加的 Set方法 和 Get方法 的 声明,并未实质上添加了成员变量 和 Set/Get 方法的实现.

当然,如果一定要给分类添加属性,可以使用Runtime库中得下面三个关联对象的API来进行实现.

// 添加关联对象
void objc_setAssociatedObject(id object, const void * key, id value, objc_AssociationPolicy policy);

// 获取关联对象
id objc_getAssociatedObject(id object, const void * key);

// 移除所有关联对象
void objc_removeAssociatedObjects(id object);

注: 底层源码基于 objc4 - 818.2 版本.

关联对象最终并不是存储在被关联对象本身的内存中.

所有关联对象底层由一个 AssociationManager 共同管理, AssociationManager里面含有一个 线程安全的 HashMap 类型 MapStorage;

MapStorage 的Key 为objc_object泛型的指针类型. Value 为 ObjectAssociationMap;

class AssociationManager {
    using Storage = ExplicitInitDenseMap<DisguisedPtr<objc_object>, ObjectAssociationMap>;
    static Storage mapStorage;

    ...
};

在 ObjectAssociationMap 中, key 为指针类型, value 则是 ObjcAssociation.

typedf DenseMap<const void *, ObjcAssocation> ObjectAssociationMap; 

OjbcAssociation 主要存储的是 策略类型 以及 值.

class ObjcAssociation {
    uintptr_t _policy;
    id _value;

    ...
};

整体结构图如下所示.


IT界无底坑洞栋主 欢迎加Q骚扰:676758285