Objective-C語言在Category中實(shí)現(xiàn)屬性

做開發(fā)時(shí)我們常常會(huì)需要在已經(jīng)實(shí)現(xiàn)了的類中增加一些方法主慰,這時(shí)候我們一般會(huì)用Category的方式來做。但是這樣做我們也只能擴(kuò)展一些方法鲫售,而有時(shí)候我們更多的是想給它增加一個(gè)屬性共螺。由于類已經(jīng)是編譯好的了,就不能靜態(tài)的增加成員了情竹,這樣我們就需要自己來實(shí)現(xiàn)getter和setter方法了藐不,在這些方法中動(dòng)態(tài)的讀寫屬性變量來實(shí)現(xiàn)屬性。一種比較簡單的做法是使用Objective-C運(yùn)行時(shí)的這兩個(gè)方法:

void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy);
id objc_getAssociatedObject(id object, const void *key);

這兩個(gè)方法可以讓一個(gè)對(duì)象和另一個(gè)對(duì)象關(guān)聯(lián)秦效,就是說一個(gè)對(duì)象可以保持對(duì)另一個(gè)對(duì)象的引用佳吞,并獲取那個(gè)對(duì)象。有了這些棉安,就能實(shí)現(xiàn)屬性功能了。 policy可以設(shè)置為以下這些值:

enum { 
OBJC_ASSOCIATION_ASSIGN = 0, 
OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, 
OBJC_ASSOCIATION_COPY_NONATOMIC = 3, 
OBJC_ASSOCIATION_RETAIN = 01401,
OBJC_ASSOCIATION_COPY = 01403
};

這些值跟屬性定義中的nonatomic铸抑,copy贡耽,retain等關(guān)鍵字的功能類似。
Example
下面是一個(gè)屬性自定義getter和setter的例子:

NSString const * kExposeController = @"exposeController";

- (UIViewController *)exposeController { 
return (UIViewController *)objc_getAssociatedObject(self, kExposeController);
}
- (void)setExposeController:(UIViewController *)exposeController { 
objc_setAssociatedObject(self, kExposeController, exposeController, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

可以看出使用objc_setAssociatedObject和objc_getAssociatedObject函數(shù)可以很方便的實(shí)現(xiàn)屬性的getter和setter鹊汛。
一個(gè)很方便的宏
為此蒲赂,我特意寫了一個(gè)Synthesize宏,可以提供@synthesize類似的功能刁憋±淖欤可以支持兩種最常用的屬性:非原子retain和assign屬性(如果需要其他類型的屬性可自行修改)。

#import <objc/runtime.h>

#define SYNTHESIZE_CATEGORY_OBJ_PROPERTY(propertyGetter, propertySetter) 
- (id) propertyGetter {
 return objc_getAssociatedObject(self, @selector( propertyGetter ));}

- (void) propertySetter (id)obj{ 
objc_setAssociatedObject(self, @selector( propertyGetter ), obj, OBJC_ASSOCIATION_RETAIN_NONATOMIC); }

#define SYNTHESIZE_CATEGORY_VALUE_PROPERTY(valueType, propertyGetter, propertySetter) 
- (valueType) propertyGetter { 
valueType ret = {0}; 
[objc_getAssociatedObject(self, @selector( propertyGetter )) getValue:&ret]; 
return ret;
 } 

- (void) propertySetter (valueType)value{
 NSValue *valueObj = [NSValue valueWithBytes:&value objCType:@encode(valueType)];
 objc_setAssociatedObject(self, @selector( propertyGetter ), valueObj, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 
}

用這個(gè)宏只需要指定相關(guān)屬性的類型至耻,getter和setter就可以快速的實(shí)現(xiàn)一個(gè)屬性若皱。比如在UIAlert的Category實(shí)現(xiàn)一個(gè)非原子retain屬性u(píng)serInfo,以及一個(gè)assign的類型為CGRect的customArea屬性:

@interface UIAlertView (Ex)
@property(nonatomic, retain) id userInfo;
@property(nonatomic) CGRect customArea;
@end

@implementation UIAlertView (Ex)
SYNTHESIZE_CATEGORY_OBJ_PROPERTY(userInfo, setUserInfo:)SYNTHESIZE_CATEGORY_VALUE_PROPERTY(CGRect, customArea, setCustomArea:)
@end
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末尘颓,一起剝皮案震驚了整個(gè)濱河市走触,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌疤苹,老刑警劉巖互广,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡惫皱,警方通過查閱死者的電腦和手機(jī)像樊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來旅敷,“玉大人生棍,你說我怎么就攤上這事∩ㄖ澹” “怎么了足绅?”我有些...
    開封第一講書人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長韩脑。 經(jīng)常有香客問我氢妈,道長,這世上最難降的妖魔是什么段多? 我笑而不...
    開封第一講書人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任首量,我火速辦了婚禮,結(jié)果婚禮上进苍,老公的妹妹穿的比我還像新娘加缘。我一直安慰自己,他們只是感情好觉啊,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開白布拣宏。 她就那樣靜靜地躺著,像睡著了一般杠人。 火紅的嫁衣襯著肌膚如雪勋乾。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,031評(píng)論 1 285
  • 那天嗡善,我揣著相機(jī)與錄音辑莫,去河邊找鬼。 笑死罩引,一個(gè)胖子當(dāng)著我的面吹牛各吨,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播袁铐,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼揭蜒,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了昭躺?” 一聲冷哼從身側(cè)響起忌锯,我...
    開封第一講書人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎领炫,沒想到半個(gè)月后偶垮,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年似舵,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了脚猾。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡砚哗,死狀恐怖龙助,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蛛芥,我是刑警寧澤提鸟,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站仅淑,受9級(jí)特大地震影響称勋,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜涯竟,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一赡鲜、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧庐船,春花似錦银酬、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至篓冲,卻和暖如春壮韭,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背纹因。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留琳拨,地道東北人瞭恰。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像狱庇,于是被迫代替她去往敵國和親惊畏。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345

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