如何实现给分类“添加成员变量”?

  • 默认情况下,因为分类底层结构的限制,不能添加成员变量到分类中。但可以通过关联对象来间接实现
  • 关联对象提供了以下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)

key的常见用法

objc_AssociationPolicy修饰符

给分类添加属性实例

假如已经有一个 XGPerson的类,现在我们需要扩展这个类,并且添加一个 age 属性

#import "XGPerson.h"

// 分类属性是不会生成 get\set 方法的,如果不重写这两个方法,就无法正常使用属性
@interface XGPerson (Test) @property (nonatomic,assign) int age; @end
#import "XGPerson+Test.h"
#import <objc/runtime.h> @implementation XGPerson (Test) - (void)setAge:(int)age{ // @selector(age) 这个参数只要传一个地址指针就可以
objc_setAssociatedObject(self, @selector(age), @(age), OBJC_ASSOCIATION_ASSIGN);
} - (int)age{ // 隐式参数
// _cmd = @selectior(age)
return [objc_getAssociatedObject(self, _cmd) intValue];
}

调用:

        XGPerson* p1 = [[XGPerson alloc]init];
p1.name = @"p1";
p1.age = ; XGPerson* p2 = [[XGPerson alloc]init];
p2.name = @"p2";
p2.age = ; NSLog(@"p1Name:%@ p1Age:%i----p2Name:%@ p2Age:%i",p1.name,p1.age,p2.name,p2.age);

输出:

-- ::38.666084+ 关联对象(增加分类属性)[:] p1Name:p1  p1Age:----p2Name:p2  p2Age:

关联对象的原理

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

  AssociationsManager
  AssociationsHashMap
  ObjectAssociationMap
  ObjcAssociation

  • objc4源码解读:objc-references.mm

  

  • 关联对象存储结构图

  1. 关联对象并不是存储在被关联对象本身内存中
  2. 关联对象存储在全局的统一的一个AssociationsManager中
  3. 设置关联对象为nil,就相当于是移除关联对象

移除对象关联引用源码:

当一个对象触发 dealloc 时会调用下面的代码:

可以看出,在调用 dealloc 方法时,不需要我们手动去删除 对象关联信息,它会自己去调用 删除对象关联信息

【OC底层】AssociatedObject 关联对象的更多相关文章

  1. OC - runtime 之关联对象

    header{font-size:1em;padding-top:1.5em;padding-bottom:1.5em} .markdown-body{overflow:hidden} .markdo ...

  2. AssociatedObject关联对象原理实现

    介绍 关联对象(AssociatedObject)是Objective-C 2.0运行时的一个特性,允许开发者对已经存在的类在扩展中添加自定义的属性.在实际生产过程中,比较常用的方式是给分类(Cate ...

  3. Objective-C——关联对象

    动态语言 OC是一种动态语言,它的方法,对象的类型都是到运行的时候才能够确定的.所以这就使得OC存在了关联对象这一强大的机制. 关联对象 所谓关联对象,其实就是我们在运行时对一个已存在的对象上面绑定一 ...

  4. 使用关联对象(AssociatedObject)为UIButton添加Block响应

    在开发中,要给UIButton添加点击事件的话,通常的做法是这样的 UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem]; [ ...

  5. 关联对象 AssociatedObject 完全解析

    我们在 iOS 开发中经常需要使用分类(Category),为已经存在的类添加属性的需求,但是使用 @property 并不能在分类中正确创建实例变量和存取方法. 不过,通过 Objective-C ...

  6. Runtime之成员变量&属性&关联对象

    上篇介绍了Runtime类和对象的相关知识点,在4.5和4.6小节,也介绍了成员变量和属性的一些方法应用.本篇将讨论实现细节的相关内容. 在讨论之前,我们先来介绍一个很冷僻但又很有用的一个关键字:@e ...

  7. Runtime - Associated Objects (关联对象) 的实现原理

    主要围绕3个方面说明runtime-Associated Objects (关联对象) 1. 使用场景 2.如何使用 3.底层实现 3.1  实现原理 3.2 关联对象被存储在什么地方,是不是存放在被 ...

  8. iOS Category 添加属性实现原理 - 关联对象

    iOS Category 添加属性实现原理 - 关联对象 RunTime为Category动态关联对象 使用RunTime给系统的类添加属性,首先需要了解对象与属性的关系.对象一开始初始化的时候其属性 ...

  9. Runtime - 关联对象使用方法及注意点

    大家都知道在分类里,可以间接的添加属性,运用runtime关联对象. 如下图,只是声明了btnClickedCount的set, get方法而已 并没有生成_btnClickedCount 成员变量, ...

随机推荐

  1. onscroll事件没有响应的原因以及vue.js中添加onscroll事件监听的方法

    1 onscroll事件失效 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...

  2. idea springboot应用启动

    在idea里启动springboot应用最好使用 spring-boot:run 如果通过运行main方法启动应用,会找不到页面

  3. 实现自定义Session

    1. 回话状态接口 /// <summary> /// 会话状态策略接口 /// </summary> public partial interface ISessionStr ...

  4. JQuery 选择器 筛选器

    什么是jQuery对象 参考:http://jquery.cuishifeng.cn/css.html jQuery 对象就是通过jQuery包装DOM对象后产生的对象.jQuery 对象是 jQue ...

  5. windows设置VMware开机启动并开启虚拟机

    1.建立开机脚本 新建start-vm.bat内容如下: "C:\Program Files (x86)\VMware\VMware Workstation\vmrun.exe" ...

  6. Jmeter 测试 JMS (Java Message Service)/ActiveMQ 性能

    前言 JMS介绍:JMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送 ...

  7. Linux学习之CentOS(五)----网卡的配置

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/3 ...

  8. 机器学习vs深度学习及其知识点

    人工智能如火如荼,可以遇见这将会是近10年最大的创新机会.那么到底什么是人工智能? 机器学习和神经网络什么关系? 卷积神经网络中的矩阵内积是怎么计算的?

  9. Coroutine及其实现

    线程是内核对外提供的服务,应用程序可以通过系统调用让内核启动线程,由内核来负责线程调度和切换.线程在等待IO操作时线程变为unrunnable状态会触发上下文切换.现代操作系统一般都采用抢占式调度,上 ...

  10. 【gp数据库】查询系统表看模式下所有表的分布键信息

    Greenplum是关系型的分布式数据库,需要存储的数据库在进入数据库时,将先进行数据分布的处理工作,讲一个表的数据平均分不到每个节点上,并为每个表指定一个分发列(distribute Column) ...