iOS 給分類category添加屬性

一转培、問題:給分類(category)添加屬性

  1. 最近遇到一個問題:需要在一個類的Category中添加屬性先鱼;
  2. 可以通過 Category 給一個現(xiàn)有的類添加屬性遮晚,但是卻不能添加實例變量辆憔;
  3. 解決方案:通過runtime建立關(guān)聯(lián)引用;

二涤躲、解決:runtime建立關(guān)聯(lián)引用

1.引入runtime頭文件

#import <objc/runtime.h>

2.添加屬性

可以在分類(即.m文件)中添加棺耍,也可以在分類的頭文件(即.h文件)中添加。

@interface UIView (EmptyView)

@property (nonatomic, strong) UIButton *hideButton;

@end

3.實現(xiàn)getter种樱、setter

1).在implementation中添加屬性的getter和setter方法蒙袍。

//getter 
- (UIButton *)hideButton {
    UIButton *_hideButton = objc_getAssociatedObject(self, @selector(hideButton));
    if (!_hideButton) {
        _hideButton = [UIButton buttonWithType:UIButtonTypeCustom];
        _hideButton.frame = CGRectMake(self.bounds.size.width/2-110, 260, 220, 44);
        _hideButton.backgroundColor = [UIColor brownColor];
        [_hideButton setTitle:@"Hide" forState:UIControlStateNormal];
        objc_setAssociatedObject(self, @selector(hideButton), _hideButton, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    return _hideButton;
}

//setter
- (void)setHideButton:(UIButton *)hideButton {
    objc_setAssociatedObject(self, @selector(hideButton), hideButton, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

2).在hideButton中使用的objc_getAssociatedOject方法,Object-C中描述如下:

/** 
 * Returns the value associated with a given object for a given key.
 * 
 * @param object The source object for the association.
 * @param key The key for the association.
 * 
 * @return The value associated with the key \e key for \e object.
 * 
 * @see objc_setAssociatedObject
 */
OBJC_EXPORT id objc_getAssociatedObject(id object, const void *key)
    OBJC_AVAILABLE(10.6, 3.1, 9.0, 1.0);

  • <a href = http://blog.leichunfeng.com/blog/2015/06/26/objective-c-associated-objects-implementation-principle/>這個函數(shù)先根據(jù)對象地址在 AssociationsHashMap 中查找其對應(yīng)的 ObjectAssociationMap 對象缸托,如果能找到則進(jìn)一步根據(jù) key 在 ObjectAssociationMap 對象中查找這個 key 所對應(yīng)的關(guān)聯(lián)結(jié)構(gòu) ObjcAssociation 左敌,如果能找到則返回 ObjcAssociation 對象的 value 值,否則返回 nil 俐镐;</a>
  • 也就是在和self建立了關(guān)聯(lián)引用的所有對象中通過key找到某一個特定的對象,如果有返回該對象的value哺哼,否則佩抹,返回 nil 。
  • objc_getAssociatedObject有兩個參數(shù)取董,第一個參數(shù)為從該object中獲取關(guān)聯(lián)對象棍苹,第二個參數(shù)為想要獲取關(guān)聯(lián)對象的key;

對于第二個參數(shù)const void *key,有以下四種推薦的key值:

  • 聲明 static char kAssociatedObjectKey; 茵汰,使用 &kAssociatedObjectKey 作為 key 值;
  • 聲明 static void *kAssociatedObjectKey = &kAssociatedObjectKey;枢里,使用 kAssociatedObjectKey 作為key值;
  • selector 蹂午,使用 getter 方法的名稱作為key值栏豺;
  • 而使用_cmd可以直接使用該@selector的名稱,即hideButton豆胸,并且能保證改名稱不重復(fù)奥洼。(與上一種方法相同)

3).在setHideButton中使用的objc_setAssociatedObject方法,Object-C中描述如下:

/** 
 * Sets an associated value for a given object using a given key and association policy.
 * 
 * @param object The source object for the association.
 * @param key The key for the association.
 * @param value The value to associate with the key key for object. Pass nil to clear an existing association.
 * @param policy The policy for the association. For possible values, see “Associative Object Behaviors.”
 * 
 * @see objc_setAssociatedObject
 * @see objc_removeAssociatedObjects
 */
OBJC_EXPORT void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)
    OBJC_AVAILABLE(10.6, 3.1, 9.0, 1.0);

參數(shù)說明:

  • objectkey同于objc_getAssociatedObject;
  • value:需要和object建立關(guān)聯(lián)引用對象的value晚胡;
  • policy:關(guān)聯(lián)策略灵奖,等同于給property添加關(guān)鍵字,具體說明如下表關(guān)聯(lián)策略

關(guān)聯(lián)策略

|關(guān)聯(lián)策略 |等價屬性|說明|
|------|------|------|------|
|OBJC_ASSOCIATION_ASSIGN| @property (assign) or @property (unsafe_unretained)| 弱引用關(guān)聯(lián)對象|
|OBJC_ASSOCIATION_RETAIN_NONATOMIC| @property (strong, nonatomic)| 強(qiáng)引用關(guān)聯(lián)對象估盘,且為非原子操作|
|OBJC_ASSOCIATION_COPY_NONATOMIC| @property (copy, nonatomic)| 復(fù)制關(guān)聯(lián)對象瓷患,且為非原子操作|
|OBJC_ASSOCIATION_RETAIN| @property (strong, atomic)| 強(qiáng)引用關(guān)聯(lián)對象,且為原子操作
|OBJC_ASSOCIATION_COPY| @property (copy, atomic)| 復(fù)制關(guān)聯(lián)對象遣妥,且為原子操作|

4.對添加的屬性操作

例如將添加的hideButton屬性添加到View中

- (void)showHideButton {
    if (!self.hideButton.superview) {
        [self addSubview:self.hideButton];
    }
}

參考資料

  1. <a href = http://blog.leichunfeng.com/blog/2015/06/26/objective-c-associated-objects-implementation-principle>Objective-C Associated Objects 的實現(xiàn)原理</a>;
  2. <a href = http://www.reibang.com/p/3cbab68fb856>給分類(Category)添加屬性</a>;
  3. <a href = http://www.reibang.com/p/535d1574cb86>iOS Category中添加屬性和成員變量的區(qū)別</a>擅编。

Github鏈接

<a href = https://github.com/JixinZhang/CategoryDemo/tree/master>查看代碼請點擊這里</a>

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市燥透,隨后出現(xiàn)的幾起案子沙咏,更是在濱河造成了極大的恐慌辨图,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件肢藐,死亡現(xiàn)場離奇詭異故河,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)吆豹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進(jìn)店門鱼的,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人痘煤,你說我怎么就攤上這事凑阶。” “怎么了衷快?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵宙橱,是天一觀的道長。 經(jīng)常有香客問我蘸拔,道長师郑,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任调窍,我火速辦了婚禮宝冕,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘邓萨。我一直安慰自己地梨,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布缔恳。 她就那樣靜靜地躺著宝剖,像睡著了一般。 火紅的嫁衣襯著肌膚如雪褐耳。 梳的紋絲不亂的頭發(fā)上诈闺,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天,我揣著相機(jī)與錄音铃芦,去河邊找鬼雅镊。 笑死,一個胖子當(dāng)著我的面吹牛刃滓,可吹牛的內(nèi)容都是我干的仁烹。 我是一名探鬼主播,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼咧虎,長吁一口氣:“原來是場噩夢啊……” “哼卓缰!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤征唬,失蹤者是張志新(化名)和其女友劉穎捌显,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體总寒,經(jīng)...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡扶歪,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了摄闸。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片善镰。...
    茶點故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖年枕,靈堂內(nèi)的尸體忽然破棺而出炫欺,到底是詐尸還是另有隱情,我是刑警寧澤熏兄,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布品洛,位于F島的核電站,受9級特大地震影響摩桶,放射性物質(zhì)發(fā)生泄漏毫别。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一典格、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧台丛,春花似錦耍缴、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至侠坎,卻和暖如春蚁趁,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背实胸。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工他嫡, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人庐完。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓钢属,卻偏偏與公主長得像,于是被迫代替她去往敵國和親门躯。 傳聞我的和親對象是個殘疾皇子淆党,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,601評論 2 353

推薦閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 1,709評論 0 9
  • 1.runtime體驗 1.1.引言 運行時作為面試題中高階問題必不可少的一個技能點。經(jīng)常面試官會問道是否使...
    2897275c8a00閱讀 931評論 0 5
  • 聽說小北在德州又發(fā)燒了39度染乌,在不停喝水的情況下山孔,又退燒了,真是來的快荷憋,去的快台颠! 最近半年多時間里,小北時不時的喊...
    海濱閱讀 170評論 0 1
  • 文 陶蓉 有時候我就覺得繪本并不是孩子們的專利台谊,大人一樣適合蓉媳。昨天出差途中,和同事聊起了春節(jié)锅铅,感慨現(xiàn)在過年的方式越...
    陶蓉子閱讀 247評論 0 3
  • 預(yù)告,我現(xiàn)在腦子是空白的贼邓,這是一段漫無目的的流水賬阶冈,寫到我餓了就結(jié)束。 我有無數(shù)個在昨天給明天制定的計劃塑径,我羞愧告...
    植夫閱讀 270評論 7 7