美文网首页
iOS - 关联对象

iOS - 关联对象

作者: 搬砖的crystal | 来源:发表于2022-11-08 14:00 被阅读0次

一、简介

关联对象的使用一般用于给 Category 添加成员变量。我们知道,分类添加属性只能生成 setter/getter 方法的声明,不能自动生成实现,所以我们需要自己实现两个方法。

1.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 类型使用,不然会报错。

2.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 中,关系如下:


从上图可以看出,关联对象的底层实现依赖下面四个核心对象:
  • AssociationsManager
  • AssociationsHashMap
  • ObjectAssociationMap
  • ObjectionAssociation

它们之间的关系:AssociationsHashMap 里存储着某个对象的关联对象 Map 表,即 ObjectAssociationMap,这个表存储了多个关联对象,因为在分类里可以给对象添加多个属性,也就要设置多个关联对象, ObjectAssociationMap 中就是我们添加的关联对象,比如 name,由 ObjectionAssociation 存储值和策略,当我们将关联对象(即 value值,例如 person.name = nil)设为 nil 时,AssociationsMap 自动删除这条关联对象;当我们调用 objc_removeAssociatedObjects(id object) 方法时,就是移除某个对象的所有关联对象,即上图中 AssociationHashMap 需要移除对象的关联对象 Map 表;

相关文章

  • iOS关联对象技术原理

    iOS关联对象技术原理 iOS关联对象技术原理

  • iOS底层原理总结 - 关联对象实现原理

    iOS底层原理总结 - 关联对象实现原理 iOS底层原理总结 - 关联对象实现原理

  • iOS Objective-C 关联对象

    iOS Objective-C 关联对象 1. 关联对象简介 对于关联对象,我们熟悉它的地方就是给分类添加属性。虽...

  • iOS对象关联

    什么是关联对象 关联对象是指某个OC对象通过一个唯一的key连接到一个类的实例上。 举个例子:xiaoming是P...

  • iOS:关联对象

    目录一,添加属性二,基本知识三,底层原理四,注意点 一,添加属性 1,在类中添加属性,系统会自动生成带下划线的成员...

  • iOS 关联对象

    在平时的工作中经常碰到给类别添加属性的操作,那么实现思路是怎么样的呢? 代码实现:新建一个Person类和Pers...

  • iOS 关联对象

    可以不改变源码的情况下增加实例变量。可与分类配合使用,为分类增加属性。(类别是不能添加成员变量的(property...

  • iOS 关联对象

    关联对象简单的说就是运用oc语言的运行时特性(runtime),给类别加属性(当然不止加属性).正常的类中创建一个...

  • iOS 关联对象

    在上一篇文章中我们理解了load&&initialize,Category---为什么只能加方法不能加属性[htt...

  • iOS 关联对象

    objc_setAssociatedObject 关联对象使用关联,我们可以不用修改类的定义而为其对象增加存储空间...

网友评论

      本文标题:iOS - 关联对象

      本文链接:https://www.haomeiwen.com/subject/okpwtdtx.html