4. OC语法-关联对象

一、思考:如何实现给分类“添加成员变量”?

  • 默认情况下,因为分类底层结构的限制,不能添加成员变量到分类中。但可以通过关联对象来间接实现

  • 关联对象提供了以下API

// 添加关联对象
/*
id object: 要关联的对象
const void * key: 关联属性的key
id value: 要关联的属性值
objc_AssociationPolicy policy: 策略
*/
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)

二、key的常见用法

  • 方式一: 使用指针变量作为key
// 为啥使用static, 不要用全局的指针变量, 外界可以修改, 导致数据出错
static void *MyKey = &MyKey;
objc_setAssociatedObject(obj, MyKey, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC) 
objc_getAssociatedObject(obj, MyKey)
  • 方式二: 使用常量的地址作为key
// 为啥用char, 因为char类型的常量只有1个字节
static const char MyKey;
objc_setAssociatedObject(obj, &MyKey, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC) 
objc_getAssociatedObject(obj, &MyKey)
  • 方式三: 使用属性名作为key
objc_setAssociatedObject(obj, @"property", value, OBJC_ASSOCIATION_COPY_NONATOMIC); 
objc_getAssociatedObject(obj, @"property");
  • 方式四(推荐):使用get方法的@selecor作为key
objc_setAssociatedObject(obj, @selector(getter), value, OBJC_ASSOCIATION_RETAIN_NONATOMIC) 
// _cmd == @selector(getter)
// objc_getAssociatedObject(obj, @selector(getter))
objc_getAssociatedObject(self, _cmd);

三、objc_AssociationPolicy

在这里插入图片描述

四、关联对象的原理

  • 实现关联对象技术的核心对象有

    • AssociationsManager
    • AssociationsHashMap
    • ObjectAssociationMap
    • ObjcAssociation
  • objc4源码解读:objc-references.mm
    在这里插入图片描述

五、关联对象的原理

void objc_setAssociatedObject(id object, const void * key, id value, objc_AssociationPolicy policy)
  • 关联对象并不是存储在被关联对象本身内存中
  • 关联对象存储在全局的统一的一个AssociationsManager中
  • 设置关联对象为nil,就相当于是移除关联对象

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值