今天看了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 关联对象的学习的更多相关文章

  1. objc_setAssociatedObject 关联对象

    使用场景:在分类中,不允许创建实例变量,这里就解决了此问题 参考: https://www.cnblogs.com/someonelikeyou/p/7162613.html 属性的实质:就是实例变量 ...

  2. ios 关联对象运用 objc_setAssociatedObject

    点按钮的时候,给alertView添加一个关联对象(被点击这个按钮), objc_setAssociatedObject(alert, &kRepresentedObject, sender, ...

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

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

  4. iOS开发--Runtime的简单使用之关联对象

    一.Runtime关联对象的方法简介: 在<objc/runtime.h>中,有三个关联的方法,分别是: objc_setAssociatedObject objc_getAssociat ...

  5. iOS - Objective-C 关联(objc_setAssociatedObject、objc_getAssociatedObject、objc_removeAssociatedObjects)

    关联是指把两个对象相互关联起来,使得其中的一个对象作为另外一个对象的一部分. 关联特性只有在Mac OS X V10.6以及以后的版本上才是可用的. 在类的定义之外为类增加额外的存储空间 使用关联,我 ...

  6. 【iOS】关联属性存取数据

    有时候我们需要在现有的类存放一些额外的信息,通常的做法是继承一个子类,然后定义新增加的属性,然而如果我们为每个需要的类都添加一个类显得太麻烦了,objc提供了一个关联属性的特性,可以给一个对象关联一个 ...

  7. OC - runtime 之关联对象

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

  8. 关联对象 AssociatedObject 完全解析

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

  9. Effective Objective-C 2.0 — 第10条:在既有类中使用关联对象存放自定义数据

    可以通过“关联对象”机制来把两个对象连起来 定义关联对象时可指定内存管理语义,用以模仿定义属性时所采用的“拥有关系”与“非拥有关系” 只有在其他做法不可行时才应选用关联对象,因为这种做法通常会引入难于 ...

随机推荐

  1. python 中property函数如何实现

    实际上,在python中property(fget,fset,fdel,doc)函数不是一个真正的函数,他其实是拥有很多特殊方法的类. 这特殊类总的很多方法完成了property函数中的所有工作,涉及 ...

  2. MapReduce源码分析之JobSubmitter(一)

    JobSubmitter,顾名思义,它是MapReduce中作业提交者,而实际上JobSubmitter除了构造方法外,对外提供的唯一一个非private成员变量或方法就是submitJobInter ...

  3. ListView中pointToPosition()方法使用具体演示样例

    MainActivity例如以下: package cc.testpointtoposition; import java.util.ArrayList; import java.util.HashM ...

  4. mysql命令 SHOW TABLE STATUS LIKE '%city%'; 查看表的状态可以查看表的创建时间

    show status like '%handler_read_key%'; #走索引的命令的数量. #查看存储引擎 mysql> show variables like '%engine%'; ...

  5. 结构体成员管理AVClass AVOption之2AVOption,设置选项值

    AVOption用于在FFmpeg中描述结构体中的成员变量.一个AVOption可以包含名称,简短的帮助信息,取值等. 上篇文章中概括了AVClass,AVOption和目标结构体之间的关系.以AVF ...

  6. head&amp;&amp;tail

    //參考<Linux shell脚本攻略 第2版> 1,head a)打印前10行: ubuntu@VM-62-13-ubuntu:~$ head file b)打印前5行: ubuntu ...

  7. hbuilder mui如何监听搜索框点击清除按钮

    监听代码如下: mui(".mui-icon-clear")[0].addEventListener('tap',function(){    console.log(456)}) ...

  8. 【matlab】绘制双三次插值函数曲线

    想要的效果: 编程时要用到分段函数曲线的绘制方法:..+.*(分段条件). 需要注意的是:函数表达式中的乘除和乘方都要加“.”.因为一般的函数都是数在乘变量运算. x=-:; a=-0.5; w=ab ...

  9. PHP面向过程和面向对象

    php程序编写分为面向过程和面向对象.两者在功能实现上没有区别,但是在代码编写上区别很大,面向过程的代码很乱,不易管理,而面向对象把常用的功能封装为一个类,这样代码清楚多了. 下面举个小例子说明一下: ...

  10. timus1965(不错的贪心)

    题意是:给你一个1-n的排列,要你把这个排列分成两个序列,且这个两个序列都满足单调性. 题解: 1.首先假设找出的两个序列都是单调递增的(都是单调递减的同理) 那么很容易可以想到,将新加入的数放入到某 ...