iOS category底層真面目

我們知道撒顿,所有的OC類和對(duì)象,在runtime層都是用struct表示的,category也不例外突想,在runtime層,category用結(jié)構(gòu)體category_t(在objc-runtime-new.h中可以找到此定義),它包含了:

1)猾担、類的名字(name)

2)袭灯、類(cls)

3)、category中所有給類添加的實(shí)例方法的列表(instanceMethods)

4)绑嘹、category中所有添加的類方法的列表(classMethods)

5)稽荧、category實(shí)現(xiàn)的所有協(xié)議的列表(protocols)

6)、category中添加的所有屬性(instanceProperties)

typedef struct category_t {?

?const char *name;

? ? classref_t cls;

? ? struct method_list_t *instanceMethods;? ??

struct method_list_t *classMethods;? ?

?struct protocol_list_t *protocols;? ?

?struct property_list_t *instanceProperties;

} category_t;

從category的定義也可以看出category的可為(可以添加實(shí)例方法工腋,類方法姨丈,甚至可以實(shí)現(xiàn)協(xié)議,添加屬性)和不可為(無法添加實(shí)例變量)擅腰。

需要注意的有兩點(diǎn):

1)蟋恬、category的方法沒有“完全替換掉”原來類已經(jīng)有的方法,也就是說如果category和原來類都有methodA趁冈,那么category附加完成之后歼争,類的方法列表里會(huì)有兩個(gè)methodA

2)、category的方法被放到了新方法列表的前面渗勘,而原來類的方法被放到了新方法列表的后面沐绒,這也就是我們平常所說的category的方法會(huì)“覆蓋”掉原來類的同名方法,這是因?yàn)檫\(yùn)行時(shí)在查找方法的時(shí)候是順著方法列表的順序查找的旺坠,它只要一找到對(duì)應(yīng)名字的方法洒沦,就會(huì)罷休^_^,殊不知后面可能還有一樣名字的方法价淌。

分類(category) > 本類 > 父類申眼。即,優(yōu)先調(diào)用cateory中的方法蝉衣,然后調(diào)用本類方法括尸,最后調(diào)用父類方法。

注意:category是在運(yùn)行時(shí)加載的病毡,不是在編譯時(shí)濒翻。

category不能添加成員變量

實(shí)際上,Category實(shí)際上允許添加屬性的啦膜,同樣可以使用@property有送,但是不會(huì)生成_變量(帶下劃線的成員變量),也不會(huì)生成添加屬性的getter和setter方法的實(shí)現(xiàn)僧家,所以雀摘,盡管添加了屬性,也無法使用點(diǎn)語法調(diào)用getter和setter方法(實(shí)際上八拱,點(diǎn)語法是可以寫的阵赠,只不過在運(yùn)行時(shí)調(diào)用到這個(gè)方法時(shí)候會(huì)報(bào)方法找不到的錯(cuò)誤涯塔,如下圖)。但實(shí)際上可以使用runtime去實(shí)現(xiàn)Category為已有的類添加新的屬性并生成getter和setter方法

需要注意的有兩點(diǎn):

1)清蚀、category的方法沒有“完全替換掉”原來類已經(jīng)有的方法匕荸,也就是說如果category和原來類都有methodA,那么category附加完成之后枷邪,類的方法列表里會(huì)有兩個(gè)methodA榛搔。

2)、category的方法被放到了新方法列表的前面东揣,而原來類的方法被放到了新方法列表的后面践惑,這也就是我們平常所說的category的方法會(huì)“覆蓋”掉原來類的同名方法,這是因?yàn)檫\(yùn)行時(shí)在查找方法的時(shí)候是順著方法列表的順序查找的救斑,它只要一找到對(duì)應(yīng)名字的方法,就會(huì)罷休真屯,殊不知后面可能還有一樣名字的方法脸候。

分類的執(zhí)行優(yōu)先級(jí)

4.1在本類和分類有相同的方法時(shí),優(yōu)先調(diào)用分類的方法再調(diào)用本類的方法绑蔫。

4.2如果有兩個(gè)分類运沦,他們都實(shí)現(xiàn)了相同的方法,如何判斷誰先執(zhí)行配深?分類執(zhí)行順序可以通過targets,Build Phases,Complie Source進(jìn)行調(diào)節(jié)携添,注意執(zhí)行順序是從上到下的。(只有兩個(gè)相同方法名的分類)

1)無法向類中添加新的實(shí)例變量篓叶。

(2)名稱沖突烈掠,即當(dāng)類別中的方法與原始類方法名稱沖突時(shí),類別具有更高的優(yōu)先級(jí)缸托。

(3)如果多個(gè)分類中都有和原有類中同名的方法, 那么調(diào)用該方法的時(shí)候執(zhí)行誰由編譯器決定左敌;編譯器會(huì)執(zhí)行最后一個(gè)參與編譯的分類中的方法

實(shí)例變量本質(zhì)上就是成員變量,只是實(shí)例是針對(duì)類而言俐镐,實(shí)例是指類的聲明矫限。{?? }中的yourButton就是實(shí)例變量。id 是OC特有的類佩抹,本質(zhì)上講id等同于(void *)叼风。所以id data屬于實(shí)例變量。

成員變量用于類內(nèi)部棍苹,無需與外界接觸的變量无宿。因?yàn)槌蓡T變量不會(huì)生成set、get方法枢里,所以外界無法與成員變量接觸懈贺。根據(jù)成員變量的私有性经窖,為了方便訪問,所以就有了屬性變量梭灿。屬性變量的好處就是允許讓其他對(duì)象訪問到該變量(因?yàn)閷傩詣?chuàng)建過程中自動(dòng)產(chǎn)生了set 和get方法)画侣。當(dāng)然,你可以設(shè)置只讀或者可寫等堡妒,設(shè)置方法也可自定義配乱。所以,屬性變量是用于與其他對(duì)象交互的變量皮迟。

可以看到在接口 @interface 括號(hào)里面的統(tǒng)稱為”成員變量”搬泥,實(shí)例變量是成員變量中的一種!

實(shí)例變量的英文翻譯是?Instance?Variable?(object-specific storage)?

實(shí)例的英文翻譯為Instance(manifestation? of a? class)? 說的是“類的表現(xiàn)”伏尼,說明實(shí)例變量應(yīng)該是由類定義的變量忿檩!

除去基本數(shù)據(jù)類型int float ....等,其他類型的變量都叫做實(shí)例變量爆阶。

**實(shí)例變量+基本數(shù)據(jù)類型變量=成員變量**

1.分類是用于給原有類添加方法的,因?yàn)榉诸惖慕Y(jié)構(gòu)體指針中燥透,沒有屬性列表,只有方法列表辨图。所以< 原則上講它只能添加方法, 不能添加屬性(成員變量),實(shí)際上可以通過其它方式添加屬性> ;

2.分類中的可以寫@property, 但不會(huì)生成setter/getter方法, 也不會(huì)生成實(shí)現(xiàn)以及私有的成員變量(編譯時(shí)會(huì)報(bào)警告);

3.可以在分類中訪問原有類中.h中的屬性;

4.如果分類中有和原有類同名的方法, 會(huì)優(yōu)先調(diào)用分類中的方法, 就是說會(huì)忽略原有類的方法班套。所以同名方法調(diào)用的優(yōu)先級(jí)為 分類 > 本類 > 父類。因此在開發(fā)中盡量不要覆蓋原有類;

5.如果多個(gè)分類中都有和原有類中同名的方法, 那么調(diào)用該方法的時(shí)候執(zhí)行誰由編譯器決定故河;編譯器會(huì)執(zhí)行最后一個(gè)參與編譯的分類中的方法吱韭。

分類與類擴(kuò)展的區(qū)別:

1 類別中原則上智能增加方法

能添加屬性的問題只是通過runtime解決沒有setter/getter的問題而已

2 類擴(kuò)展不僅可以增加方法,還可以增加實(shí)例變量(或者屬性)鱼的,只是該實(shí)例變量默認(rèn)只是@private類型的(只能在自身類使用理盆,不能再子類或者其他地方使用)

3 類擴(kuò)展中聲明的方法沒有被實(shí)現(xiàn),編譯器會(huì)報(bào)警凑阶,但是類別中聲明的方法沒有被實(shí)現(xiàn)熏挎,編譯器也會(huì)有警告。這是因?yàn)轭悢U(kuò)展是在編譯階段被添加到類中晌砾,而類別是在運(yùn)行時(shí)添加到類中

4 類擴(kuò)展不能像類別那樣擁有獨(dú)立的實(shí)現(xiàn)部分 @implementaton 部分坎拐。也就是說,類擴(kuò)展所聲明的方法必須依托對(duì)應(yīng)的類的實(shí)現(xiàn)部分來實(shí)現(xiàn)

5 定義在.m文件中的類擴(kuò)展方法為私有方法养匈,定義在.h中的類擴(kuò)展的方法為公有方法哼勇。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市呕乎,隨后出現(xiàn)的幾起案子积担,更是在濱河造成了極大的恐慌,老刑警劉巖猬仁,帶你破解...
    沈念sama閱讀 206,723評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件帝璧,死亡現(xiàn)場(chǎng)離奇詭異先誉,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)的烁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門褐耳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人渴庆,你說我怎么就攤上這事铃芦。” “怎么了襟雷?”我有些...
    開封第一講書人閱讀 152,998評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵刃滓,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我耸弄,道長(zhǎng)咧虎,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,323評(píng)論 1 279
  • 正文 為了忘掉前任计呈,我火速辦了婚禮砰诵,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘震叮。我一直安慰自己胧砰,他們只是感情好鳍鸵,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,355評(píng)論 5 374
  • 文/花漫 我一把揭開白布苇瓣。 她就那樣靜靜地躺著,像睡著了一般偿乖。 火紅的嫁衣襯著肌膚如雪击罪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,079評(píng)論 1 285
  • 那天贪薪,我揣著相機(jī)與錄音媳禁,去河邊找鬼。 笑死画切,一個(gè)胖子當(dāng)著我的面吹牛竣稽,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播霍弹,決...
    沈念sama閱讀 38,389評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼毫别,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了典格?” 一聲冷哼從身側(cè)響起岛宦,我...
    開封第一講書人閱讀 37,019評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎耍缴,沒想到半個(gè)月后砾肺,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體挽霉,經(jīng)...
    沈念sama閱讀 43,519評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,971評(píng)論 2 325
  • 正文 我和宋清朗相戀三年变汪,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了侠坎。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,100評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡疫衩,死狀恐怖硅蹦,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情闷煤,我是刑警寧澤童芹,帶...
    沈念sama閱讀 33,738評(píng)論 4 324
  • 正文 年R本政府宣布,位于F島的核電站鲤拿,受9級(jí)特大地震影響假褪,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜近顷,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,293評(píng)論 3 307
  • 文/蒙蒙 一生音、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧窒升,春花似錦缀遍、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蓉媳,卻和暖如春譬挚,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背酪呻。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評(píng)論 1 262
  • 我被黑心中介騙來泰國打工减宣, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人玩荠。 一個(gè)月前我還...
    沈念sama閱讀 45,547評(píng)論 2 354
  • 正文 我出身青樓漆腌,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國和親阶冈。 傳聞我的和親對(duì)象是個(gè)殘疾皇子闷尿,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,834評(píng)論 2 345

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