iOS Objective-C的objc runtime isa指針相關(guān)

Objective-C是一個(gè)面向?qū)ο笳Z(yǔ)言慰技,每一個(gè)對(duì)象都是一個(gè)類(lèi)的實(shí)例阴挣。那類(lèi)和方法調(diào)用的本質(zhì)是什么呢?runtime究竟又是什么呢流纹?這篇文章主要是記錄了解到的相關(guān)知識(shí)。這部分知識(shí)應(yīng)該是OC中最基礎(chǔ)的部分了违诗,對(duì)于深入理解某些知識(shí)還是很重要的漱凝。

runtime

runtime的概念在官方文檔中有介紹。整理如下诸迟,runtime其實(shí)是一個(gè)runtime庫(kù)茸炒,能夠提供OC語(yǔ)言的動(dòng)態(tài)屬性。這個(gè)庫(kù)是開(kāi)源的阵苇,我們可以在GitHub下載它的源碼看看壁公。
源碼中objc.h中有很多基本類(lèi)型的定義,比如對(duì)象和方法:

// 對(duì)象
typedef struct objc_object {
    Class isa;
} *id;

// 方法
typedef struct objc_selector    *SEL;    
typedef id          (*IMP)(id, SEL, ...);

開(kāi)頭的第二個(gè)問(wèn)題解決了绅项,接下來(lái)研究第一個(gè)問(wèn)題紊册。這個(gè)問(wèn)題在源碼中也可以找到答案。

對(duì)象

源碼中的Object.h中定義如下:

@interface Object
{
    Class isa;  /* A pointer to the instance's class structure */
}

isa是一個(gè)指向?qū)嵗念?lèi)結(jié)構(gòu)體的指針快耿,那Class到底是什么類(lèi)型呢囊陡?
源碼中的objc_class.h中定義如下:

struct objc_class {         
    struct objc_class *isa; 
    struct objc_class *super_class; 
    const char *name;       
    long version;
    long info;
    long instance_size;
    struct objc_ivar_list *ivars;

#if defined(Release3CompatibilityBuild)
    struct objc_method_list *methods; //Objective-C 2.0
#else
    struct objc_method_list **methodLists; //Objective-C 1.0
#endif

    struct objc_cache *cache;
    struct objc_protocol_list *protocols;
};

接下來(lái)搞清楚幾個(gè)重要屬性都是什么,
isa:是一個(gè)Class類(lèi)型的指針润努。 每個(gè)Object都有isa指針关斜,指向?qū)ο蟮念?lèi),而Class里也有個(gè)isa的指針, 指向meteClass(元類(lèi))铺浇。元類(lèi)保存了類(lèi)方法的列表痢畜。當(dāng)類(lèi)方法被調(diào)用時(shí),先會(huì)從本身查找類(lèi)方法的實(shí)現(xiàn),如果沒(méi)有丁稀,元類(lèi)會(huì)向他父類(lèi)查找該方法吼拥。同時(shí)注意的是:元類(lèi)(meteClass)也是類(lèi),它也是對(duì)象线衫。元類(lèi)也有isa指針,它的isa指針最終指向的是一個(gè)根元類(lèi)(root meteClass).根元類(lèi)的isa指針指向本身凿可,這樣形成了一個(gè)封閉的內(nèi)循環(huán)。

class示意圖.jpg

super_class:指向父類(lèi)授账,沒(méi)有賊為NULL枯跑。
name:類(lèi)的名稱(chēng)
ivars:成員變量的數(shù)組
methods:方法的定義列表,對(duì)象的方法定義都保存在類(lèi)的可變區(qū)域中白热。methodLists是一個(gè)指針的指針敛助,通過(guò)修改該指針指向的指針的值,就可以實(shí)現(xiàn)動(dòng)態(tài)地為某一個(gè)類(lèi)增加成員方法屋确。這也是Category實(shí)現(xiàn)的原理纳击。同時(shí)也說(shuō)明了為什么Category只可為對(duì)象增加成員方法,卻不能增加成員變量

方法調(diào)用

Objective-c是一門(mén)動(dòng)態(tài)語(yǔ)言攻臀,調(diào)用方法的時(shí)候焕数,在運(yùn)行時(shí),動(dòng)態(tài)的查找方法刨啸,然后調(diào)用相應(yīng)的函數(shù)地址堡赔。

SEL

SEL又叫選擇器,是表示一個(gè)方法的selector的指針呜投。Objective-C 在編譯時(shí)加匈,會(huì)根據(jù)方法的名字生成一個(gè)用來(lái)區(qū)分這個(gè)方法的唯一的一個(gè)ID,本質(zhì)上就是一個(gè)字符串仑荐,即Int類(lèi)型的地址雕拼,這個(gè)字符串就是SEL。只要方法名稱(chēng)相同粘招,那么它們的ID就是相同的啥寇。
objc.h中的IMP實(shí)際上就是一個(gè)函數(shù)指針,指向方法實(shí)現(xiàn)的首地址洒扎。

在Objective-C中辑甜,消息直到運(yùn)行時(shí)才綁定到方法實(shí)現(xiàn)上。編譯器會(huì)將消息表達(dá)式[receiver message]轉(zhuǎn)化為一個(gè)消息函數(shù)的調(diào)用袍冷,即objc_msgSend磷醋,將消息接收者和方法名作為其基礎(chǔ)參數(shù),如以下所示:

objc_msgSend(receiver, selector)
消息發(fā)送.gif

當(dāng)消息發(fā)送給一個(gè)對(duì)象時(shí)胡诗,objc_msgSend通過(guò)對(duì)象的isa指針獲取到類(lèi)的結(jié)構(gòu)體邓线,然后在methods里面查找方法的selector淌友。如果沒(méi)有找到selector,則找到其父類(lèi)骇陈,并在父類(lèi)的分發(fā)表里面查找震庭。依此,會(huì)一直沿著類(lèi)的繼承體系到達(dá)NSObject類(lèi)你雌。一旦定位到selector器联,函數(shù)就獲取到了實(shí)現(xiàn)的入口點(diǎn),并傳入相應(yīng)的參數(shù)來(lái)執(zhí)行方法的具體實(shí)現(xiàn)婿崭。如果最后沒(méi)有定位到selector拨拓,則會(huì)走消息轉(zhuǎn)發(fā)流程。
為了加速消息的處理氓栈,運(yùn)行時(shí)系統(tǒng)緩存使用過(guò)的selector及對(duì)應(yīng)的方法的地址千元。

參考文章:
Objective-C對(duì)象模型及應(yīng)用
OC Runtime第一篇---類(lèi)與對(duì)象
Objective-C Runtime 運(yùn)行時(shí)之三:方法與消息

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市颤绕,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌祟身,老刑警劉巖奥务,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異袜硫,居然都是意外死亡氯葬,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)婉陷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)帚称,“玉大人,你說(shuō)我怎么就攤上這事秽澳〈扯茫” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵担神,是天一觀的道長(zhǎng)楼吃。 經(jīng)常有香客問(wèn)我,道長(zhǎng)妄讯,這世上最難降的妖魔是什么孩锡? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮亥贸,結(jié)果婚禮上躬窜,老公的妹妹穿的比我還像新娘。我一直安慰自己炕置,他們只是感情好荣挨,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布男韧。 她就那樣靜靜地躺著,像睡著了一般垦沉。 火紅的嫁衣襯著肌膚如雪煌抒。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,007評(píng)論 1 284
  • 那天厕倍,我揣著相機(jī)與錄音寡壮,去河邊找鬼。 笑死讹弯,一個(gè)胖子當(dāng)著我的面吹牛况既,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播组民,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼棒仍,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了臭胜?” 一聲冷哼從身側(cè)響起莫其,我...
    開(kāi)封第一講書(shū)人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎耸三,沒(méi)想到半個(gè)月后乱陡,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡仪壮,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年憨颠,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片积锅。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡爽彤,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出缚陷,到底是詐尸還是另有隱情适篙,我是刑警寧澤,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布蹬跃,位于F島的核電站匙瘪,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏蝶缀。R本人自食惡果不足惜丹喻,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望翁都。 院中可真熱鬧碍论,春花似錦、人聲如沸柄慰。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至藏研,卻和暖如春敬矩,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蠢挡。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工弧岳, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人业踏。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓禽炬,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親勤家。 傳聞我的和親對(duì)象是個(gè)殘疾皇子腹尖,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

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