今天看了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