一.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ò)誤之處還望指正,謝謝!