iOSRuntime之objc_setAssociatedObject初步運(yùn)用(小白篇)

一.objc/runtime.h相關(guān)介紹

Objecitve-C的重要特性是Runtime(運(yùn)行時(shí)),在Interacting with the Runtime(交互運(yùn)行)中,運(yùn)行時(shí)函數(shù)部分,蘋果給出了/usr/lib/libobjc.A.dylib庫,這個(gè)共享庫提供支持動(dòng)態(tài)屬性的objective - c語言,通過其接口,可以用于開發(fā)將其他語言運(yùn)行于Objective-C上的中間層(橋接層),庫里的函數(shù)定義為純C語言。

二.objc_setAssociatedObject注解

objc_setAssociatedObject來把一個(gè)對(duì)象與另外一個(gè)對(duì)象進(jìn)行關(guān)聯(lián)。該函數(shù)需要四個(gè)參數(shù):源對(duì)象object,獲取被關(guān)聯(lián)者的索引key,被關(guān)聯(lián)者對(duì)象value和一個(gè)關(guān)聯(lián)策略objc_AssociationPolicy。

OBJC_EXPORT void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)
id object                     :表示關(guān)聯(lián)者,是一個(gè)對(duì)象,變量名理所當(dāng)然也是object
 const void *key               :獲取被關(guān)聯(lián)者的索引key
 id value                      :被關(guān)聯(lián)者,這里是一個(gè)block
 objc_AssociationPolicy policy : 關(guān)聯(lián)時(shí)采用的協(xié)議,有assign,retain,copy等協(xié)議,一般使用OBJC_ASSOCIATION_RETAIN_NONATOMIC

三.具體運(yùn)用:(本文具體運(yùn)用只舉一個(gè)最簡(jiǎn)單的例子,將UIButton與Block關(guān)聯(lián))

  • UIButton的擴(kuò)展

.h文件

typedef void (^btnBlock)();

@interface UIButton (Block)

- (void)handelWithBlock:(btnBlock)block;

@end

.m文件

#import "UIButton+Block.h"
#import <objc/runtime.h>

static const char btnKey;//注意這里聲明了一個(gè)靜態(tài)變量用來作索引key

@implementation UIButton (Block)

- (void)handelWithBlock:(btnBlock)block
{
    if (block)
    {
        objc_setAssociatedObject(self, &btnKey, block, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    
    [self addTarget:self action:@selector(btnAction) forControlEvents:UIControlEventTouchUpInside];
}

- (void)btnAction
{
  //獲取block對(duì)象
    btnBlock block = objc_getAssociatedObject(self, &btnKey);
    block();
}


@end

對(duì)以上類擴(kuò)展的簡(jiǎn)單運(yùn)用代碼如下:

#import "ViewController.h"
#import "UIButton+Block.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    UIButton *button = [[UIButton alloc] init];
    [button setTitle:@"測(cè)試按鈕1" forState:UIControlStateNormal];
    button.frame = CGRectMake(50, 50, 150, 50);
    button.backgroundColor = [UIColor redColor];
    [self.view addSubview:button];
    [button handelWithBlock:^{
        NSLog(@"我被點(diǎn)擊了!");
    }];
}

@end

斷開關(guān)聯(lián)

斷開關(guān)聯(lián)是使用objc_setAssociatedObject函數(shù),傳入nil值即可。
使用函數(shù)objc_removeAssociatedObjects可以斷開所有關(guān)聯(lián)

個(gè)人理解,objc_setAssociatedObject成功的將button對(duì)象與block對(duì)象關(guān)聯(lián)在一起,當(dāng)用戶觸發(fā)了點(diǎn)擊事件時(shí):

    btnBlock block = objc_getAssociatedObject(self, &btnKey);
    block();

block被獲取到,并開始執(zhí)行.

所以就可以在下面這個(gè)block代碼塊里處理點(diǎn)擊事件了。

    [button handelWithBlock:^{
        NSLog(@"我被點(diǎn)擊了!");
    }];

這就是objc_setAssociatedObject的關(guān)聯(lián),還是不怎么明白的朋友,把我上面的例子copy下來,自己再模擬器上運(yùn)行一下,點(diǎn)擊一下Button應(yīng)該就都明白了。

詳細(xì)理解:

適用場(chǎng)景:
一些UI控件(不僅僅是文中的控件),當(dāng)這些控件有觸發(fā)事件并且需要同時(shí)調(diào)用另外的執(zhí)行方法或是代理方法時(shí),都可以通過本文中介紹objc_setAssociatedObject的方法來關(guān)聯(lián)起來(UI控件和block關(guān)聯(lián),block代碼塊中實(shí)現(xiàn)另外的執(zhí)行方法或代理方法),利用block方式來實(shí)現(xiàn)相應(yīng)的執(zhí)行方法或是代理方 法。這樣就可以利用起來block的優(yōu)點(diǎn)了,比如block可以直接捕獲上下文中的量。
到此,這篇文章就結(jié)束了,如果還有哪位小伙伴們不懂得可以在下面留言,看到必回!另:本人如有理解錯(cuò)誤之處還望指正,謝謝!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 2,032評(píng)論 0 9
  • 這篇文章完全是基于南峰子老師博客的轉(zhuǎn)載 這篇文章完全是基于南峰子老師博客的轉(zhuǎn)載 這篇文章完全是基于南峰子老師博客的...
    西木閱讀 30,872評(píng)論 33 466
  • title : 取消IOS9對(duì)http的請(qǐng)求限制category : IOS 取消IOS9對(duì)http的請(qǐng)求限制 ...
    袁俊亮技術(shù)博客閱讀 963評(píng)論 0 0
  • 躺在床上 若有所思 像是一個(gè)垂危的老人 頹廢的氣息包圍著我 我是誰 我在哪里 這一刻 我很累 很累 很累 突然的累...
    小紙閱讀 337評(píng)論 0 0

友情鏈接更多精彩內(nèi)容