iOS OC中分類Category實(shí)現(xiàn)原理

一蛛勉、概念

1.前言

category是Objective-C?2.0之后添加的語(yǔ)言特性廷雅,

category的主要作用是為已經(jīng)存在的類添加方法届谈。

2.設(shè)計(jì)思想

?Objective-C 中的 Category 就是對(duì)裝飾模式的一種具體實(shí)現(xiàn)晓褪。它的主要作用是在不改變?cè)蓄惖那疤嵯拢瑒?dòng)態(tài)地給這個(gè)類添加一些方法扎筒。

在 Objective-C 中的具體體現(xiàn)為:實(shí)例(類)方法、屬性和協(xié)議酬姆。

二嗜桌、使用場(chǎng)景

1.給現(xiàn)有的類添加方法;

2.將一個(gè)類的實(shí)現(xiàn)拆分成多個(gè)獨(dú)立的源文件;

?好處:

? a)可以減少單個(gè)文件的體積

? b)可以把不同的功能組織到不同的category里

? c)可以由多個(gè)開(kāi)發(fā)者共同完成一個(gè)類

? d)可以按需加載想要的category 等等辞色。

3.聲明私有的方法骨宠。

三、實(shí)現(xiàn)原理

1.我們不主動(dòng)引入 Category 的頭文件,Category 中的方法都會(huì)被添加進(jìn)主類中层亿。我們可以通過(guò)?- performSelector:?等方式 對(duì) Category 中的相應(yīng)方法進(jìn)行調(diào)用

?a)將 Category 和它的主類(或元類)注冊(cè)到哈希表中桦卒;

?b)如果主類(或元類)已實(shí)現(xiàn),那么重建它的方法列表匿又。

2.在這里分了兩種情況進(jìn)行處理:Category 中的實(shí)例方法和屬性被整合到主類中方灾;而類方法則被整合到元類中(關(guān)于對(duì)象、類和元類的更多細(xì)節(jié)碌更,可以參考我前面的博文《Objective-C對(duì)象模型》)裕偿。另外,對(duì)協(xié)議的處理比較特殊痛单,Category 中的協(xié)議被同時(shí)整合到了主類和元類中嘿棘。

3.注意到,不管是哪種情況旭绒,最終都是通過(guò)調(diào)用staticvoid?remethodizeClass(Class cls)?函數(shù)來(lái)重新整理類的數(shù)據(jù)的鸟妙。

四、category結(jié)構(gòu)體

1.所有的OC類和對(duì)象挥吵,在runtime層都是用struct表示的重父,category也不例外,在runtime層蔫劣,category用結(jié)構(gòu)體category_t.

2.category結(jié)構(gòu)體的定義:

structcategory_t?{

constchar*name;//類的名字(name)

classref_t?cls;//類(cls)

? ? ??struct?method_list_t?*instanceMethods;?//category中所有給類添加的實(shí)例方法的列表(instanceMethods)

structmethod_list_t?*classMethods;//category中所有添加的類方法的列表(classMethods)

structprotocol_list_t?*protocols;?//category實(shí)現(xiàn)的所有協(xié)議的列表(protocols)

structproperty_list_t?*instanceProperties;//category中添加的所有屬性(instanceProperties)

};

3.從category的定義也可以看出category可以添加實(shí)例方法坪郭,類方法;可以遵守協(xié)議脉幢,添加屬性歪沃;但無(wú)法添加實(shí)例變量。

注意嫌松,在category中可以有屬性(property)沪曙,但是該屬性只是生成了getter和setter方法的聲明,并沒(méi)有產(chǎn)生對(duì)應(yīng)的實(shí)現(xiàn)萎羔,更不會(huì)添加對(duì)應(yīng)的實(shí)例變量液走。如果想為實(shí)例對(duì)象添加實(shí)例變量,可以嘗試使用關(guān)聯(lián)引用技術(shù)贾陷。

五缘眶、添加方法列表

原理圖:


1.添加方法列表的時(shí)候是后添加的在新形成的列表前部,這也是為什么在有多個(gè)category中有同名方法時(shí)髓废,后編譯的在調(diào)用時(shí)會(huì)“覆蓋”前面已編譯的方法巷懈。其實(shí)方法本身并沒(méi)有被覆蓋,只是調(diào)用的時(shí)候是從上而下查找方法列表慌洪,當(dāng)運(yùn)行時(shí)找到對(duì)應(yīng)的方法名后就去忙著調(diào)用了顶燕,并不會(huì)管后面的同名方法凑保。

2.關(guān)于load方法:

? 其實(shí)在上面的源碼中也可以看到,category 中對(duì)load方法的處理過(guò)并沒(méi)有什么特殊。因此涌攻,可以說(shuō)category 中的 load 方法跟普通方法一樣也會(huì)對(duì)主類中的 load方法造成覆蓋欧引,只不過(guò) runtime在自動(dòng)調(diào)用主類和 category中的 load方法時(shí)是直接使用各自方法的指針進(jìn)行調(diào)用的。所以我們感覺(jué)不到category對(duì)主類的影響恳谎。其實(shí)手動(dòng)給主類發(fā)送load 消息時(shí)芝此,調(diào)用的將會(huì)是分類中的load 方法。

六惠爽、注意項(xiàng)

1.Category 有一個(gè)非常容易誤用的場(chǎng)景癌蓖,那就是用 Category 來(lái)覆寫父類或主類的方法。雖然目前 Objective-C 是允許這么做的婚肆,但是這種使用場(chǎng)景是非常不推薦的租副。

2.使用?Category 來(lái)覆寫方法有很多缺點(diǎn),比如不能覆寫 Category 中的方法较性、無(wú)法調(diào)用主類中的原始實(shí)現(xiàn)等用僧,且很容易造成無(wú)法預(yù)估的行為。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末赞咙,一起剝皮案震驚了整個(gè)濱河市责循,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌攀操,老刑警劉巖院仿,帶你破解...
    沈念sama閱讀 219,039評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異速和,居然都是意外死亡歹垫,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門颠放,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)排惨,“玉大人,你說(shuō)我怎么就攤上這事碰凶∧喊牛” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 165,417評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵欲低,是天一觀的道長(zhǎng)辕宏。 經(jīng)常有香客問(wèn)我,道長(zhǎng)砾莱,這世上最難降的妖魔是什么匾效? 我笑而不...
    開(kāi)封第一講書人閱讀 58,868評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮恤磷,結(jié)果婚禮上面哼,老公的妹妹穿的比我還像新娘。我一直安慰自己扫步,他們只是感情好魔策,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著河胎,像睡著了一般闯袒。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上游岳,一...
    開(kāi)封第一講書人閱讀 51,692評(píng)論 1 305
  • 那天政敢,我揣著相機(jī)與錄音,去河邊找鬼胚迫。 笑死喷户,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的访锻。 我是一名探鬼主播褪尝,決...
    沈念sama閱讀 40,416評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼期犬!你這毒婦竟也來(lái)了河哑?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 39,326評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤龟虎,失蹤者是張志新(化名)和其女友劉穎璃谨,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體鲤妥,經(jīng)...
    沈念sama閱讀 45,782評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡佳吞,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,957評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了旭斥。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片容达。...
    茶點(diǎn)故事閱讀 40,102評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖垂券,靈堂內(nèi)的尸體忽然破棺而出花盐,到底是詐尸還是另有隱情,我是刑警寧澤菇爪,帶...
    沈念sama閱讀 35,790評(píng)論 5 346
  • 正文 年R本政府宣布算芯,位于F島的核電站,受9級(jí)特大地震影響凳宙,放射性物質(zhì)發(fā)生泄漏熙揍。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,442評(píng)論 3 331
  • 文/蒙蒙 一氏涩、第九天 我趴在偏房一處隱蔽的房頂上張望届囚。 院中可真熱鬧有梆,春花似錦、人聲如沸意系。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,996評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)蛔添。三九已至痰催,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間迎瞧,已是汗流浹背夸溶。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,113評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留凶硅,地道東北人缝裁。 一個(gè)月前我還...
    沈念sama閱讀 48,332評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像咏尝,于是被迫代替她去往敵國(guó)和親压语。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,044評(píng)論 2 355

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