第四章 協(xié)議與分類—第25條:總是為第三方類的分類名稱加前綴

分類機(jī)制通常用于向無(wú)源碼的既有類中新增功能萌抵。這個(gè)特性極為強(qiáng)大,但在使用時(shí)也很容易忽視其中可能產(chǎn)生的問(wèn)題巫湘。這個(gè)問(wèn)題在于: 分類中的方法是直接添加在類里面的娄猫,它們就好比這個(gè)類中的固有方法。將分類方法加入類中這一操作是在運(yùn)行期系統(tǒng)加載分類時(shí)完成的外冀。運(yùn)行期系統(tǒng)會(huì)把分類中的每個(gè)方法都加入類的方法列表中寡键。如果類中本來(lái)就有此方法,而分類又實(shí)現(xiàn)了一次雪隧,那么分類中的方法都加入類的方法列表中西轩。如果類中本來(lái)就有此方法,而分類又實(shí)現(xiàn)了一次脑沿,那么分類中的方法會(huì)覆蓋原來(lái)那一份實(shí)現(xiàn)代碼藕畔。實(shí)際上可能會(huì)發(fā)生很多次覆蓋,比如某個(gè)分類中的方法覆蓋了"主實(shí)現(xiàn)"中的相關(guān)方法庄拇,而另外一個(gè)分類中的方法又覆蓋了這個(gè)分類中的方法注服。多次覆蓋的結(jié)果以最后一個(gè)分類為準(zhǔn)。
比方說(shuō)措近,要給NSString添加分類溶弟,并在其中提供一些輔助方法,用于處理與HTTP URL有關(guān)的字符串熄诡。你可能會(huì)把分類寫成這樣:

@interface NSString (HTTP)

// Encode a string with URL encoding
- (NSString*)urlEncodedString;

// Decode a URL encoded string
- (NSString*)urlDecodedString;

@end

現(xiàn)在看起來(lái)沒(méi)什么問(wèn)題可很,可是诗力,如果還有一個(gè)分類也往NSString里添加方法凰浮,那會(huì)如何呢我抠?那個(gè)分類里可能也有個(gè)名叫urlEncodedString的方法,其代碼與你所添加的大同小異袜茧,但卻不能正確實(shí)現(xiàn)你所需的功能菜拓。那個(gè)分類的加載時(shí)機(jī)如果晚于你所寫的這個(gè)分類,那么其代碼就會(huì)把你的那一份覆蓋掉笛厦,這樣的話纳鼎,你在代碼中調(diào)用urlEncodedString方法時(shí),實(shí)際執(zhí)行的是那個(gè)分類里的實(shí)現(xiàn)代碼裳凸。由于其執(zhí)行結(jié)果和你預(yù)期的值不同贱鄙,所以自己所寫的那些代碼也許就無(wú)法正常運(yùn)行了。這種bug很難追查姨谷,因?yàn)槟憧赡芤庾R(shí)不到實(shí)際執(zhí)行的urlEncodedString代碼并不是自己實(shí)現(xiàn)的那一份逗宁。
要解決此問(wèn)題,一般的做法是: 以命名空間來(lái)區(qū)別各個(gè)分類的名稱與其中所定義的方法梦湘。想在Objective-C中實(shí)現(xiàn)命名空間功能瞎颗,只有一個(gè)辦法,就是給相關(guān)名稱都加上某個(gè)共用的前綴捌议。與給類名加前綴(參見(jiàn)第15條)時(shí)所應(yīng)考慮的因素相似哼拔,給分類所加的前綴也要選得恰當(dāng)才行。一般來(lái)說(shuō)瓣颅,這個(gè)前綴應(yīng)該與應(yīng)用程序或程序中其他地方所用的前綴相同倦逐。于是,我們可以給剛才那個(gè)NSString分類加上ABC前綴:

@interface NSString (ABC_HTTP)

// Encode a string with URL encoding
- (NSString*)abc_urlEncodedString;

// Decode a URL encoded string
- (NSString*)abc_urlDecodedString;

@end

從技術(shù)角度講宫补,并不是非得命名空間把各個(gè)分類的名稱區(qū)隔開(kāi)不可僻孝。即便兩個(gè)分類重名了,也不會(huì)出錯(cuò)守谓。然而這樣做不好穿铆,編譯器會(huì)發(fā)出類似下面這種警告信息:

warning: duplicate definition of category 'HTTP' on interface 'NSString'

即便加了前綴,也難保其他分類不會(huì)覆蓋你所寫的方法斋荞,然而幾率卻小了很多荞雏,因?yàn)槠渌绦驇?kù)很少會(huì)和你選用同一個(gè)前綴。這樣做也能避免類的開(kāi)發(fā)者以后在更新該類時(shí)所添加的方法與你在分類中添加方法重名平酿。比方說(shuō)凤优,假如蘋果公司決定在NSString類里添加urlEncodedString方法,而你在分類中所寫的方法又沒(méi)加前綴蜈彼,那么可能就會(huì)覆蓋蘋果公司的方法筑辨,這樣做不合適,因?yàn)镹SString類的其他使用者想得到由蘋果公司實(shí)現(xiàn)的代碼所輸出的結(jié)果幸逆,而非你所返回的那個(gè)結(jié)果棍辕。還有一種可能暮现,就是蘋果公司編寫的實(shí)現(xiàn)代碼帶有一些附加效果,該方法若為你所寫的代碼所覆蓋楚昭,則會(huì)令對(duì)象內(nèi)的數(shù)據(jù)互不一致栖袋,從而造成難于查找的bug。
此外還要記住抚太,如果向某個(gè)類的分類中加入方法塘幅,那么在應(yīng)用程序中,該類的每個(gè)實(shí)例均可調(diào)用這些方法尿贫。比方說(shuō)电媳,若是向NSString、NSArray庆亡、NSNumber這種系統(tǒng)類里添加方法匆背,那么這些類的每個(gè)實(shí)例均可調(diào)用你所加的方法,即便這些實(shí)例不是由你的代碼創(chuàng)建出來(lái)的身冀,也依然會(huì)如此钝尸。如果你無(wú)意中把自己分類里的方法名起得和其他分類一樣,或是與第三方庫(kù)所添分類中的方法重名了搂根,那么就可能出現(xiàn)奇怪的bug珍促,因?yàn)槟阋詾榇朔椒▓?zhí)行的是自己所寫的那份代碼,然而實(shí)際上卻不是剩愧。與之相似猪叙,刻意覆寫分類中的方法也不好,尤其是當(dāng)你把代碼發(fā)布為程序庫(kù)供其他開(kāi)發(fā)者使用仁卷,而他們又要依賴系統(tǒng)中現(xiàn)存的功能時(shí)穴翩,更不應(yīng)該這么做。若是其他開(kāi)發(fā)者又覆寫了同一個(gè)方法锦积,那么情況會(huì)更糟芒帕,因?yàn)闊o(wú)法確定最后到底會(huì)執(zhí)行哪份實(shí)現(xiàn)代碼。這又一次說(shuō)明了為何要給分類中的方法名加上前綴丰介。

要點(diǎn)

  • 向第三方類中添加分類時(shí)背蟆,總應(yīng)給其名稱加上你專用的前綴
  • 向第三方類中添加分類時(shí),總應(yīng)給其中的方法名加上你專用的前綴
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末哮幢,一起剝皮案震驚了整個(gè)濱河市带膀,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌橙垢,老刑警劉巖垛叨,帶你破解...
    沈念sama閱讀 221,695評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異柜某,居然都是意外死亡嗽元,警方通過(guò)查閱死者的電腦和手機(jī)敛纲,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)还棱,“玉大人载慈,你說(shuō)我怎么就攤上這事惭等≌涫郑” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 168,130評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵辞做,是天一觀的道長(zhǎng)琳要。 經(jīng)常有香客問(wèn)我,道長(zhǎng)秤茅,這世上最難降的妖魔是什么稚补? 我笑而不...
    開(kāi)封第一講書人閱讀 59,648評(píng)論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮框喳,結(jié)果婚禮上课幕,老公的妹妹穿的比我還像新娘。我一直安慰自己五垮,他們只是感情好乍惊,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,655評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著放仗,像睡著了一般润绎。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上诞挨,一...
    開(kāi)封第一講書人閱讀 52,268評(píng)論 1 309
  • 那天莉撇,我揣著相機(jī)與錄音,去河邊找鬼惶傻。 笑死棍郎,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的银室。 我是一名探鬼主播坝撑,決...
    沈念sama閱讀 40,835評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼粮揉!你這毒婦竟也來(lái)了巡李?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 39,740評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤扶认,失蹤者是張志新(化名)和其女友劉穎侨拦,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體辐宾,經(jīng)...
    沈念sama閱讀 46,286評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡狱从,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,375評(píng)論 3 340
  • 正文 我和宋清朗相戀三年膨蛮,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片季研。...
    茶點(diǎn)故事閱讀 40,505評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡敞葛,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出与涡,到底是詐尸還是另有隱情惹谐,我是刑警寧澤,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布驼卖,位于F島的核電站氨肌,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏酌畜。R本人自食惡果不足惜怎囚,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,873評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望桥胞。 院中可真熱鬧恳守,春花似錦、人聲如沸贩虾。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,357評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)整胃。三九已至颗圣,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間屁使,已是汗流浹背在岂。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,466評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蛮寂,地道東北人蔽午。 一個(gè)月前我還...
    沈念sama閱讀 48,921評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像酬蹋,于是被迫代替她去往敵國(guó)和親及老。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,515評(píng)論 2 359

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