iOS objc_setAssociatedObject 关联对象的学习
今天看了FDTemplateLayoutCell的源码,类别里面相当频繁使用了关联对象,做笔记!!!学套路
主要函数:
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);
基本说明:关联对象就是runTime界的NSMultableDictionary
objc_setAssociatedObject 相当于 setValue:forKey 进行关联value对象 objc_getAssociatedObject 用来读取对象 objc_AssociationPolicy 属性 是设定该value在object内的属性,即 assgin, (retain,nonatomic)...等 objc_removeAssociatedObjects 函数来移除一个关联对象,或者使用objc_setAssociatedObject函数将key指定的关联对象设置为nil。
相关参数
key:要保证全局唯一,key与关联的对象是一一对应关系。必须全局唯一。通常用@selector(methodName)作为key。
value:要关联的对象。
policy:关联策略。有五种关联策略。
OBJC_ASSOCIATION_ASSIGN 等价于 @property(assign)。
OBJC_ASSOCIATION_RETAIN_NONATOMIC等价于 @property(strong, nonatomic)。
OBJC_ASSOCIATION_COPY_NONATOMIC等价于@property(copy, nonatomic)。
OBJC_ASSOCIATION_RETAIN等价于@property(strong,atomic)。
OBJC_ASSOCIATION_COPY等价于@property(copy, atomic)。
使用场景:关联对象相当于实例变量,在类别(也有人管叫分类)里面,不能创建实例变量, 关联对象就可以解决这种问题。(对应属性,有对应属性的的runtime 解决方法,本篇文章主讲 关联对象学习)
基本使用:举例创建 UIButton类别
//
// UIButton+Block.h
// SectionDemo
//
// Created by HF on 2017/7/13.
// Copyright © 2017年 HF-Liqun. All rights reserved.
// #import <UIKit/UIKit.h> typedef void (^btnBlock)(id sender); @interface UIButton (Block) - (void)handelWithBlock:(btnBlock)block; @end //
// UIButton+Block.m
// SectionDemo
//
// Created by HF on 2017/7/13.
// Copyright © 2017年 HF-Liqun. All rights reserved.
// #import "UIButton+Block.h"
#import <objc/runtime.h> @implementation UIButton (Block) - (void)handelWithBlock:(btnBlock)block { if (block) {
objc_setAssociatedObject(self,@selector(btnAction:) , block, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
[self addTarget:self action:@selector(btnAction:) forControlEvents:UIControlEventTouchUpInside]; } - (void)btnAction:(id)sender
{
btnBlock block = objc_getAssociatedObject(self,@selector(btnAction:));
if (block) {
block(sender);
}
} @end
注意到标记亮粉色部分 是第二个参数 const void *key 类型通常都是通常都是会采用静态变量来作为关键字 可以自己创建 也可以使用"@selector(btnAction:) "。
自己设置静态变量做关键字:

在FDTemplateLayoutCell 中 第二个参数进一步优化,出现了_cmd 代替了 &btnKey 或者 @selector(methodName).
因为:
_cmd在Objective-C的方法中表示当前方法的selector,正如同self表示当前方法调用的对象实例。
这里强调当前,_cmd的作用域只在当前方法里,直指当前方法名@selector。例如:

这样处理好处是,该方法相对化简了繁文缛节,并且可读性良好。不容易写错key。
参考 FDTemplateLayoutCell中使用_cmd 的使用

至此,设置关联对象关键key,一共有三种写法:
(1)静态变量&btnKey
(2)@selector(methodName)
(3)_cmd
参考
(1)http://blog.csdn.net/luoyeffcs/article/details/27967193
(2)http://blog.jobbole.com/79570/
(3)http://www.jianshu.com/p/46cd19bc4b6b
(4)http://www.jianshu.com/p/fdb1bc445266
iOS objc_setAssociatedObject 关联对象的学习的更多相关文章
- objc_setAssociatedObject 关联对象
使用场景:在分类中,不允许创建实例变量,这里就解决了此问题 参考: https://www.cnblogs.com/someonelikeyou/p/7162613.html 属性的实质:就是实例变量 ...
- ios 关联对象运用 objc_setAssociatedObject
点按钮的时候,给alertView添加一个关联对象(被点击这个按钮), objc_setAssociatedObject(alert, &kRepresentedObject, sender, ...
- iOS Category 添加属性实现原理 - 关联对象
iOS Category 添加属性实现原理 - 关联对象 RunTime为Category动态关联对象 使用RunTime给系统的类添加属性,首先需要了解对象与属性的关系.对象一开始初始化的时候其属性 ...
- iOS开发--Runtime的简单使用之关联对象
一.Runtime关联对象的方法简介: 在<objc/runtime.h>中,有三个关联的方法,分别是: objc_setAssociatedObject objc_getAssociat ...
- iOS - Objective-C 关联(objc_setAssociatedObject、objc_getAssociatedObject、objc_removeAssociatedObjects)
关联是指把两个对象相互关联起来,使得其中的一个对象作为另外一个对象的一部分. 关联特性只有在Mac OS X V10.6以及以后的版本上才是可用的. 在类的定义之外为类增加额外的存储空间 使用关联,我 ...
- 【iOS】关联属性存取数据
有时候我们需要在现有的类存放一些额外的信息,通常的做法是继承一个子类,然后定义新增加的属性,然而如果我们为每个需要的类都添加一个类显得太麻烦了,objc提供了一个关联属性的特性,可以给一个对象关联一个 ...
- OC - runtime 之关联对象
header{font-size:1em;padding-top:1.5em;padding-bottom:1.5em} .markdown-body{overflow:hidden} .markdo ...
- 关联对象 AssociatedObject 完全解析
我们在 iOS 开发中经常需要使用分类(Category),为已经存在的类添加属性的需求,但是使用 @property 并不能在分类中正确创建实例变量和存取方法. 不过,通过 Objective-C ...
- Effective Objective-C 2.0 — 第10条:在既有类中使用关联对象存放自定义数据
可以通过“关联对象”机制来把两个对象连起来 定义关联对象时可指定内存管理语义,用以模仿定义属性时所采用的“拥有关系”与“非拥有关系” 只有在其他做法不可行时才应选用关联对象,因为这种做法通常会引入难于 ...
随机推荐
- mock中测试private方法,不是mock
Method method = PowerMockito.method(CategoryController.class, "getCategory",List.class);// ...
- HTML5 Canvas绘图详解 drawImage() 方法 有图有真相!
步骤 1 2 3 4 5 简介 是一个新的HTML元素,这个元素可以被Script语言(通常是JavaScript)用来绘制图形.例如可以用它来画图.合成图象.或做简单的(和不那么简单的)动画. ...
- Android WebView 常见问题
1.为WebView自定义错误显示界面: /** * 显示自定义错误提示页面,用一个View覆盖在WebView */ protected void showErrorPage() { LinearL ...
- Android Studio 使用笔记:给包重命名~~有点水
很简单,选择需要重命名的包,按下 Shift + F6 这时候出现提示,选择 Rename package 输入新的包名,Refactor按钮会变亮,点击就可以了. 注意:这个是重命名一个包名,想做 ...
- Android-Dialog风格Activity开发
1.设置窗口风格 : ①在Manifest中设置主题属性android:theme="@android:style/Theme.Dialog",或者 Theme.Holo.Dial ...
- CF 482A(Diverse Permutation-相邻距离不同数为k的1~n全排列构造)
A. Diverse Permutation time limit per test 1 second memory limit per test 256 megabytes input standa ...
- plsql programming 07 使用数据
数据类型 char, Nchar varchar2, Nvarchar2 clob, Nclob number number(9, 2); -- 定点小数, 小数点左边7位, 右边2位 number ...
- gcc 编译 连接 生成可执行文件
gcc c语言编译器 g++ c++编译器 gcc a.c 生成默认的a.out 可执行文件 ./a.out 来执行 gcc -c a.c 编译生成 a.o 目标文件 可以检查语法错误 gcc ...
- Android Studio下通过Gradle配置实现资源文件的模块化
当开发一个app模块个数很多的时候,资源文件就会特别多,布局也会多起来,这时所有的layout都放在同一个目录下,就会显得臃肿,而且不好找相应的布局. 最近看到相关资料,发现在Android Stud ...
- ViewPager页面切换特效
ViewPager页面切换特效如下效果 看效果: 效果1: 效果2: 下面就开始讲解如何实现这两个页面翻转效果 1.首先你得会ViewPager控件的使用(废话!现在还有人不会使用吗???!!) 2. ...