iOS中OC給Category添加屬性

引:

很多人知道可以用Category給已有的類添加一些新方法笔横,但是不同于swift中的extension吹缔,Objective-C中的Category(類別)是不支持直接添加屬性的厢塘,那如果就是需要添加新的屬性怎么辦呢?有一個辦法礁叔,使用Runtime中的關(guān)聯(lián)對象技術(shù)就可以實(shí)現(xiàn)琅关。關(guān)于Runtime的說明可以查看這篇博客:傳送門:OC中Runtime淺析

Category(類別):

對于不熟悉Category的人讥蔽,這里也先說明一下Category是什么以及怎么創(chuàng)建Category新症。

由于一些特殊的需要徒爹,我們可能要給現(xiàn)有的類添加一些新的方法,這個需求用繼承也可以做到界阁,但是會顯得比較重,這時候就可以用Category來達(dá)到目的胖喳,創(chuàng)建一個已有類的Category泡躯,可以給這個類添加你需要的方法,在使用的時候丽焊,只需要import你創(chuàng)建的Category较剃,在使用的時候還是使用原來的類,但是你會驚奇的發(fā)現(xiàn)他支持你自己在Category中添加的方法技健。

我們看到的一些名為類似“UINavigationController+Cloudox.h”的文件就是類別了重付。

那么怎么創(chuàng)建類別呢?

在工程中按住command+N來添加新文件凫乖,選擇Objectiv-C File:

image.png

在出來的界面中的File Type選擇Category,就是創(chuàng)建類別文件了弓颈,F(xiàn)ile填寫我們要加在類別尾巴上的名字帽芽,Class選擇你要添加類別的已有類,這里我們?yōu)閁INavigationController添加類別:

image.png

類別文件這樣就創(chuàng)建成功了翔冀。

添加屬性

類別可以為已有的類添加方法,但是卻不能直接添加屬性泽论,因?yàn)榧词鼓闾砑恿薂property,它既不會生成實(shí)例變量鹦赎,也不會生成setter锁施、getter方法膊毁,即使你添加了也無法使用。

所以我們首先需要自己去添加setter荆秦、getter方法,這個好辦,直接在.m文件里加就可以了刑桑,但是要真正添加可以使用的屬性拱礁,還需要利用Runtime來關(guān)聯(lián)對象,關(guān)于關(guān)聯(lián)對象的技術(shù)可以看傳送門:OC中Runtime淺析烛芬,這里只講怎么用來添加屬性,我們在setter方法里關(guān)聯(lián)一個對象,在getter方法里獲取對應(yīng)key關(guān)聯(lián)的對象揍堰,就可以啦,代碼如下季希,很簡單:

//UINavigationController+Cloudox.h文件
#import <UIKit/UIKit.h>

@interface UINavigationController (Cloudox)

@property (copy, nonatomic) NSString *cloudox;

@end

//UINavigationController+Cloudox.m文件
#import "UINavigationController+Cloudox.h"
#import <objc/runtime.h>

@implementation UINavigationController (Cloudox)

//定義常量 必須是C語言字符串
static char *CloudoxKey = "CloudoxKey";

-(void)setCloudox:(NSString *)cloudox{
    /*
     objc_AssociationPolicy參數(shù)使用的策略:
     OBJC_ASSOCIATION_ASSIGN;            //assign策略
     OBJC_ASSOCIATION_COPY_NONATOMIC;    //copy策略
     OBJC_ASSOCIATION_RETAIN_NONATOMIC;  // retain策略
     
     OBJC_ASSOCIATION_RETAIN;
     OBJC_ASSOCIATION_COPY;
     */
    /*
     關(guān)聯(lián)方法:
     objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy);
     
     參數(shù):
     * id object 給哪個對象的屬性賦值
     const void *key 屬性對應(yīng)的key
     id value  設(shè)置屬性值為value
     objc_AssociationPolicy policy  使用的策略,是一個枚舉值武学,和copy默赂,retain疾捍,assign是一樣的,手機(jī)開發(fā)一般都選擇NONATOMIC
     */
    
    objc_setAssociatedObject(self, CloudoxKey, cloudox, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

-(NSString *)cloudox{
    return objc_getAssociatedObject(self, CloudoxKey);
}


@end

注意要使用Runtime需要 import runtime 的框架,如代碼所示。

現(xiàn)在我們試試效果错负,我們按照平常的方式用UINavigationController包裝一個控制器作為根視圖:

// AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    ViewController *vc = [[ViewController alloc] init];
    UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
    self.window.rootViewController = nav;
    return YES;
}

這個視圖控制器中我們需要導(dǎo)入我們的類別文件诚镰,然后我們就會發(fā)現(xiàn)我們能夠通過self.navigationController獲取到我們新添加的名為“cloudox”的屬性了镰踏!我們可以給這個NSString類型的屬性賦值,然后獲取它進(jìn)行顯示:

#import "UINavigationController+Cloudox.h"

- (void)viewDidLoad {
    [super viewDidLoad];
    self.title = @"Demo";
    self.view.backgroundColor = [UIColor lightGrayColor];
    
    // 給UINavigationController新加的屬性賦值
    self.navigationController.cloudox = @"Hey,this is category's new property!";
    
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(([UIScreen mainScreen].bounds.size.width-300)/2, 100, 300, 50)];
    label.textColor = [UIColor whiteColor];
    label.textAlignment = NSTextAlignmentCenter;
    label.text = self.navigationController.cloudox;
    [self.view addSubview:label];
}

效果如下:

image.png

正常獲取到并且顯示藐俺,非常棒菱父。

結(jié)

以上就是給Category添加屬性的方法啦,不難野崇,只要了解Runtime中的關(guān)聯(lián)對象技術(shù)就可以輕松達(dá)到了蕴侣。


示例工程:https://github.com/Cloudox/CategoryAddPropertyDemo


查看作者首頁

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子忆某,更是在濱河造成了極大的恐慌聋呢,老刑警劉巖喂窟,帶你破解...
    沈念sama閱讀 221,820評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件厦酬,死亡現(xiàn)場離奇詭異昌讲,居然都是意外死亡短绸,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評論 3 399
  • 文/潘曉璐 我一進(jìn)店門瑟曲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事花吟〗癫迹” “怎么了造虎?”我有些...
    開封第一講書人閱讀 168,324評論 0 360
  • 文/不壞的土叔 我叫張陵萤皂,是天一觀的道長匣椰。 經(jīng)常有香客問我裆熙,道長,這世上最難降的妖魔是什么禽笑? 我笑而不...
    開封第一講書人閱讀 59,714評論 1 297
  • 正文 為了忘掉前任入录,我火速辦了婚禮,結(jié)果婚禮上佳镜,老公的妹妹穿的比我還像新娘僚稿。我一直安慰自己,他們只是感情好蟀伸,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,724評論 6 397
  • 文/花漫 我一把揭開白布蚀同。 她就那樣靜靜地躺著,像睡著了一般啊掏。 火紅的嫁衣襯著肌膚如雪蠢络。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,328評論 1 310
  • 那天迟蜜,我揣著相機(jī)與錄音刹孔,去河邊找鬼。 笑死娜睛,一個胖子當(dāng)著我的面吹牛髓霞,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播微姊,決...
    沈念sama閱讀 40,897評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼酸茴,長吁一口氣:“原來是場噩夢啊……” “哼分预!你這毒婦竟也來了兢交?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,804評論 0 276
  • 序言:老撾萬榮一對情侶失蹤笼痹,失蹤者是張志新(化名)和其女友劉穎配喳,沒想到半個月后酪穿,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,345評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡晴裹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,431評論 3 340
  • 正文 我和宋清朗相戀三年被济,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片涧团。...
    茶點(diǎn)故事閱讀 40,561評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡只磷,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出泌绣,到底是詐尸還是另有隱情钮追,我是刑警寧澤,帶...
    沈念sama閱讀 36,238評論 5 350
  • 正文 年R本政府宣布阿迈,位于F島的核電站元媚,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏苗沧。R本人自食惡果不足惜刊棕,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,928評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望待逞。 院中可真熱鬧甥角,春花似錦、人聲如沸识樱。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽牺荠。三九已至翁巍,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間休雌,已是汗流浹背灶壶。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留杈曲,地道東北人驰凛。 一個月前我還...
    沈念sama閱讀 48,983評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像担扑,于是被迫代替她去往敵國和親恰响。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,573評論 2 359