美文网首页iOS技术
iOS 基础知识之关联对象

iOS 基础知识之关联对象

作者: 谢二九 | 来源:发表于2022-06-30 09:42 被阅读0次

简介

associatedObject又称关联对象,把一个对象关联到另外一个对象身上,使两者能够产生联系。关联对象的使用场景最多的是给一个分类增加属性。通过objc_setAssociatedObject 和 objc_getAssociatedObject 方法来设置和获取关联对象。通过 objc_removeAssociatedObjects 移除关联对象。

用法

  • 设置关联对象API
/** 
 * Sets an associated value for a given object using a given key and association policy.
 * 
 * @param object The source object for the association. // 要添加关联对象的归属对象
 * @param key The key for the association. //用于设置关联对象的key
 * @param value The value to associate with the key key for object. Pass nil to clear an existing association. //通过key设置的关联对象的值
 * @param policy The policy for the association. For possible values, see “Associative Object Behaviors.” // 设置关联对象类型的策略
 * 
 * @see objc_setAssociatedObject
 * @see objc_removeAssociatedObjects
 */
OBJC_EXPORT void
objc_setAssociatedObject(id _Nonnull object, const void * _Nonnull key,
                         id _Nullable value, objc_AssociationPolicy policy)
    OBJC_AVAILABLE(10.6, 3.1, 9.0, 1.0, 2.0);
  • 其中,objc_AssociationPolicy是对设置关联对象类型的描述,有以下可选类型:
    image.png
  • 获取关联对象API
/** 
 * Returns the value associated with a given object for a given key.
 * 
 * @param object The source object for the association. //关联对象归属的对象
 * @param key The key for the association.//用于获取关联对象的key
 * 
 * @return The value associated with the key \e key for \e object.//通过key获取的关联对象的值
 * 
 * @see objc_setAssociatedObject
 */
OBJC_EXPORT id _Nullable
objc_getAssociatedObject(id _Nonnull object, const void * _Nonnull key)
    OBJC_AVAILABLE(10.6, 3.1, 9.0, 1.0, 2.0);
  • 实际使用中,我们会通过以下方式来get/set
static void *asKey = &asKey; // 内存地址
objc_setAssociatedObject(obj, asKey, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC)
objc_getAssociatedObject(obj, asKey)

static char asKey;
objc_setAssociatedObject(obj, &asKey, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC)
objc_getAssociatedObject(obj, &asKey)

使用属性名作为key
objc_setAssociatedObject(obj, @"property", value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
objc_getAssociatedObject(obj, @"property");

使用get方法的@selecor作为key
objc_setAssociatedObject(obj, @selector(getter), value, OBJC_ASSOCIATION_RETAIN_NONATOMIC)
objc_getAssociatedObject(obj, @selector(getter))

实现原理

关联对象并不是存储在被关联对象本身内存中,关联对象是通过AssociationsManager的全局类来做管理。
实现关联对象技术的核心对象有:

  • AssociationsManager
  • AssociationsHashMap
  • ObjectAssociationMap
  • ObjcAssociation
image.png

存储模型:


image.png

答疑

关联对象如何创建weak属性
  • 使用中间对象方案。用中间方案弱引用被关联的对象,将中间对象存储起来。
  • 使用blcok方案。block弱持有被关联对象,将block存起来,get方法中读取block并执行block,返回弱引用对象
分类能否添加成员变量?如果可以,如何给Category添加成员变量?
  • 不能直接给Category添加成员变量,但是可以间接实现Category有成员变量的效果
    • 添加关联对象: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)

相关文章

  • iOS 基础知识之关联对象

    简介 associatedObject又称关联对象,把一个对象关联到另外一个对象身上,使两者能够产生联系。关联对象...

  • iOS关联对象技术原理

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

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

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

  • iOS之关联对象

    我们在 iOS 开发中经常需要使用分类(Category),为已经存在的类添加属性的需求,但是使用@propert...

  • iOS~runtime之关联对象

    什么是runtime? RunTime又叫运行时。OC就是运行时机制,也就是在运行时候的一些机制,其中最主要的是消...

  • iOS之AssociateObject(关联对象)

    简介 AssociateObject 一般用于对已有对象的参数扩展,可认为是一种比较偷懒的继承方式,搭配Categ...

  • iOS底层之关联对象

    首先我们来简单的描述一下分类的一些基本概念:1、用来给类添加新方法2、不能给类添加成员属性,添加了成员变量,也无法...

  • iOS底层之关联对象

    首先我们来回忆一个经典的面试题 Category能否添加成员变量?如果可以,如何给Category添加成员变量? ...

  • iOS Objective-C 关联对象

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

  • iOS对象关联

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

网友评论

    本文标题:iOS 基础知识之关联对象

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