美文网首页iOS面试-底层
iOS原理篇(四):关联对象

iOS原理篇(四):关联对象

作者: 75b9020bd6db | 来源:发表于2019-05-14 00:39 被阅读108次
  • 关联对象的使用场合
  • 关联对象的基本使用
  • 关联对象的底层原理

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

关联对象提供了以下API:

// 1.添加关联对象:
void objc_setAssociatedObject(id object, const void * key, id value, objc_AssociationPolicy policy)
// 2.获得关联对象:
id objc_getAssociatedObject(id object, const void * key)
// 3.移除所有的关联对象
void objc_removeAssociatedObjects(id object)

在添加关联对象的方法中有一个policy属性,它是一个枚举值,对应我们平时定义属性时设置的修饰词:

二、关联对象的基本使用
使用关联对象需要#import <objc/runtime.h>

// 给DJTPerson创建一个分类,添加一个name属性
@interface DJTPerson (Test)
@property (nonatomic, copy) NSString *name;
@end

@implementation DJTPerson (Test)
/**
* 第一种写法:创建一个void*类型的指针作为key,它存着自己的地址,只要唯一就行
*/
static const void *DJTNameKey = &DJTNameKey;
- (void)setName:(NSString *)name
{
    objc_setAssociatedObject(self, DJTNameKey, name, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (NSString *)name
{
    return objc_getAssociatedObject(self, &DJTNameKey);
}

/**
* 第二种写法:既然是void*类型,使用char类型的地址,节省空间
*/
static const char DJTNameKey;
- (void)setName:(NSString *)name
{
    objc_setAssociatedObject(self, &DJTNameKey, name, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (NSString *)name
{
    return objc_getAssociatedObject(self, &DJTNameKey);
}

/**
* 第三种写法:使用属性名作为key,其实也是传的内存地址
*/
- (void)setName:(NSString *)name
{
    objc_setAssociatedObject(self, @"name", name, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (NSString *)name
{
    return objc_getAssociatedObject(self, @"name");
}

/**
* 第四种写法:使用get方法的@selector作为key,这种写法的好处是它返回的是一个结构体指针,写错方法名会有错误提示
*/
- (void)setName:(NSString *)name
{
    objc_setAssociatedObject(self, @selector(name), name, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (NSString *)name
{
    //@selector(name)等价于隐式参数_cmd
    return objc_getAssociatedObject(self, @selector(name));
   // return objc_getAssociatedObject(self, _cmd);
}
@end

三、关联对象的底层原理
关联对象并不是存储在被关联对象本身的内存中,通过分析底层实现,它存储在由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原理篇:关联对象

    前言 Swift中不能再extension中为类添加存储属性,如何利用关联对象变相添加属性呢? 关联对象相关API...

  • iOS关联对象技术原理

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

  • iOS CoreAnimation专题

    iOS CoreAnimation专题——原理篇(四)动画时间控制

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

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

  • IOS基础知识-关联对象原理篇

    Category能否添加成员变量?如果可以,如何给Category添加成员变量?答:不能直接添加成员变量,但是可以...

  • iOS Objective-C 关联对象

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

  • iOS对象关联

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

  • iOS:关联对象

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

  • iOS 关联对象

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

网友评论

    本文标题:iOS原理篇(四):关联对象

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