iOS 关联对象的实现原理

文章目录前言一般使用void objc_setAssociatedObjectobjc_getAssociatedObject关联对象的实现原理前言关联对象的使用一般用于给Category添加成员变量一般使用我们知道 分类添加属性只能生成setter getter方法的声明不能自动生成实现 所以我们需要自己实现两个方法void objc_setAssociatedObject全称 :void objc_setAssociatedObject(id object, const void *ke
摘要由CSDN通过智能技术生成

前言

关联对象的使用一般用于给Category添加成员变量

一般使用

我们知道 分类添加属性只能生成setter getter方法的声明
不能自动生成实现 所以我们需要自己实现两个方法

void objc_setAssociatedObject

全称 :

void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)

参数 :

  • id object : 给哪个对象添加属性 这里要给自己添加属性 用self
  • const void *key : 根据key获取关联对象的属性的值 只要是一个指针就好了
  • id value : 关联的值 也就是setter方法传入的值给属性去保存
  • objc_AssociationPolicy policy : 保存策略
typedef OBJC_ENUM(uintptr_t, objc_AssociationPolicy) {
   
    OBJC_ASSOCIATION_ASSIGN = 0,           /**< Specifies a weak reference to the associated object. */
    OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, /**< Specifies a strong reference to the associated object. 
                                            *   The association is not made atomically. */
    OBJC_ASSOCIATION_COPY_NONATOMIC = 3,   /**< Specifies that the associated object is copied. 
                                            *   The association is not made atomically. */
    OBJC_ASSOCIATION_RETAIN = 01401,       /**< Specifies a strong reference to the associated object.
                                            *   The association is made atomically. */
    OBJC_ASSOCIATION_COPY = 01403          /**< Specifies that the associated object is copied.
                                            *   The association is made atomically. */
};

对应内存管理方案找就好了 就跟平常属性添加关键字一样
关联对象需要什么样的内存管理方法 就使用哪个方案

用于setter方法

@property (nonatomic, assign) int weight;

在分类中有这样一个属性
setter方法 :

- (void)setWeight:(int)weight {
   
    objc_setAssociatedObject(self, @"weight", [NSNumber numberWithInt:weight], OBJC_ASSOCIATION_ASSIGN);
}

注意 int类型的变量需要转成NSNumber类型使用
不然会报错

[NSNumber numberWithInt:weight]

别的类型一般不需要转

objc_getAssociatedObject

全称 :

id objc_getAssociatedObject(id object, const void *key)

用于getter方法

- (int)weight {
   
    return [objc_getAssociatedObject(self, @"weight") intValue];
}

这里需要取出来是一个NSNumber类型 所以后面加了intValue
一般不需要加
setter方法中weight关联了一个NSNumber对象才需要加

关联对象的实现原理

核心对象

  • AssociationsManager
  • AssociationsHashMap
  • ObjectAssociationMap
  • ObjcAssociation

Map可以想象成字典 都是一对一的关系

核心对象之间的关系

class AssociationsManager {
   
    // associative references: object pointer -> PtrPtrHashMap.
    // AssociationsManager中只有一个变量AssociationsHashMap
    static AssociationsHashMap *_map;
public:
    // 构造函数中加锁
    AssociationsManager()   {
    AssociationsManagerLock.lock(); }
    // 析构函数中释放锁
    ~AssociationsManager()  {
    AssociationsManagerLock.unlock(); }
    // 构造函数、析构函数中加锁、释放锁的操作,保证了AssociationsManager是线程安全的
    
    AssociationsHashMap &associations() {
   
        // AssociationsHashMap 的实现可以理解成单例对象
        if (_map == NULL)
            _map = new AssociationsHashMap();
        
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

waxuuuu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值