关联属性

分类中不可以添加成员变量
  • 分类中可以声明属性,分类中声明属性只会生成方法的声明,但不会生成成员变量和方法的实现。
  • 分类中不可以声明成员变量,在分类中声明成员变量会报instance variables may not be placed in categories
  • 通过 Category 的底层结构可以看出分类是不支持添加成员变量的,因为 category 的结构体中没有用来存放成员变量的变量
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);
}
分类中添加关联属性
  • 添加关联对象:void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)
  • 获得关联对象:id objc_getAssociatesObject(id object, const void *key)
  • 移除所有关联对象:void objc_removeAssociatedObjects(id object)
key 的写法
  • key 必须保证是唯一的地址值
  • static void *nameKey = &nameKey:
objc_setAssociatedObject(self, nameKey, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC)
objc_getAssociatedObject(obj,nameKey)
  • static char name:
objc_setAssociatedObject(self, &name, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC)
objc_getAssociatedObject(obj,&name)
  • @selector(name)
objc_setAssociatedObject(self, @selector(name), value, OBJC_ASSOCIATION_RETAIN_NONATOMIC)
objc_getAssociatedObject(obj,_cmd)
  • @"name"
objc_setAssociatedObject(self, @"name", value, OBJC_ASSOCIATION_RETAIN_NONATOMIC)
objc_getAssociatedObject(obj,@"name")

关联对象原理

  • 实现关联对象技术的核心对象有
    1、 AssociationsManager
class AssociationsManager {
  static AssociationsHashMap *_map;
}

2、 AssociationsHashMap
class AssociationsHasMap : public unordered_map<disguised_ptr_t,ObjectAssociationMap>
3、 ObjectAssociateMap
class ObjectAssociationMap : public std::map<void *, ObjcAssociation>
4、 ObjcAssociation

class ObjcAssociation {
  uintptr_t _policy;
  id _value;
}
image.png
  • void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)中的四个参数与关联对象核心对象的关系:
    1、 object 对应 AssociationsHashMap 中的 key disguised_ptr_t ,key disguised_ptr_tobject的地址经过位运算得到的
    2、 key 对应 AssociationsMap 中的 void *
    3、 value 对应 ObjectAssociation中的 _value
    4、 policy 对应 ObjectAssociation 中的 _policy
  • 关联对象并不是存储在被关联对象本身内存中,而是存储在全局统一的一个 AssociationsMananger 中, AssociationsManager中管理着一个 AssociationsHashMapAssociationsHashMap中以传入的 objectkeyObjectAssociationMap 对象作为 valueObjectAssociationMap中以出入的 地址指针 key 作为 keyObjectAssociation 对象作为 valueObjectAssociation中存放着关联策略和关联值。
  • 当关联属性的值设置为 nil 的时候,相当于移除关联对象
  • 当对象被销毁时,会移除该对象对应的 ObjectAssociationMap
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。