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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM