為Category添加屬性

前言

在iOS開發(fā)中,category作用十分巨大,在實(shí)際項(xiàng)目中,我們可以通過添加一個類的category來實(shí)現(xiàn)任意地方調(diào)用我們已經(jīng)準(zhǔn)備好的方法,或者是對現(xiàn)有的一些類進(jìn)行擴(kuò)展。
最常見的應(yīng)用莫過于為ViewController添加分類,在分類中準(zhǔn)備好方法,這樣一來我們可以在任意控制器去調(diào)用我們準(zhǔn)備好的方法。
由于catagory的特性,使得我們在其中只能添加方法并不能添加屬性,這大大限制了我們的使用。

好在Objective-C的動態(tài)特性為我們帶來了希望。
本文通過利用Objective-C的動態(tài)特性,在運(yùn)行時動態(tài)添加屬性,動態(tài)綁定,達(dá)到category中添加屬性的目的。

分析

首先,我們先看一下property的構(gòu)成
@property的本質(zhì)其實(shí)是 ivar(實(shí)例變量)+getter+setter
也就是說,為category添加屬性的方法,其本質(zhì)上是我們?nèi)藶閯?chuàng)造一個property,通過準(zhǔn)備實(shí)例變量,自行實(shí)現(xiàn)setter方法和getter方法,來達(dá)到目的。

接下來我們看看需要用到的runtime部分。

OBJC_EXPORT void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)
    __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_1);

OBJC_EXPORT id objc_getAssociatedObject(id object, const void *key)
    __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_1);

objc_getAssociatedObject

這個方法中需要用到兩個參數(shù),objectkey
由于當(dāng)前方法在分類中,并且我們獲取的屬性也是當(dāng)前類下的屬性,object這邊指的是self。
而這里的key代表的是屬性的標(biāo)記,通過這個key來查找對應(yīng)的屬性。

//key的寫法
1、static void *key = &key;

2、static NSString *const key = @"key"; 

3、static char const * const key = "key";

objc_setAssociatedObject

這個方法中前兩個參數(shù)同上,后兩個參數(shù)分別代表關(guān)聯(lián)的屬性,和關(guān)聯(lián)策略。

關(guān)聯(lián)屬性策略如下,根據(jù)實(shí)際使用選擇關(guān)聯(lián)策略。

enum {
    OBJC_ASSOCIATION_ASSIGN = 0, //關(guān)聯(lián)對象的屬性是弱引用 

    OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, //關(guān)聯(lián)對象的屬性是強(qiáng)引用并且關(guān)聯(lián)對象不使用原子性

    OBJC_ASSOCIATION_COPY_NONATOMIC = 3, //關(guān)聯(lián)對象的屬性是copy并且關(guān)聯(lián)對象不使用原子性

    OBJC_ASSOCIATION_RETAIN = 01401, //關(guān)聯(lián)對象的屬性是copy并且關(guān)聯(lián)對象使用原子性

    OBJC_ASSOCIATION_COPY = 01403 //關(guān)聯(lián)對象的屬性是copy并且關(guān)聯(lián)對象使用原子性
};

實(shí)例

在頭文件.h中添加一個property,如:

@property (nonatomic,assign) BOOL animateInvalid;

.m實(shí)現(xiàn):

static char const * const kanimateInvalid = "kanimateInvalid";
#import <objc/runtime.h>

@implementation UIViewController (Associate)
@dynamic animateInvalid;//手動實(shí)現(xiàn)getter和setter

- (BOOL)animateInvalid{
    return [objc_getAssociatedObject(self, kanimateInvalid) boolValue];
}

- (void)setAnimateInvalid:(BOOL)animateInvalid{
    objc_setAssociatedObject(self, kanimateInvalid, @(animateInvalid), OBJC_ASSOCIATION_ASSIGN);
}

至此在category中添加屬性已經(jīng)完成。掌握方法在實(shí)際項(xiàng)目中能夠發(fā)揮十分大的作用,大大提高我們編程的效率。

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

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

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