iOS學習 --- objc_setAssociatedObject 關聯物件的學習
阿新 • • 發佈:2019-01-29
今天看了EaseBlankPageView的原始碼,類別裡面相當頻繁使用了關聯物件,做筆記!!!學套路
主要函式:
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