Objective-C Runtime技術(shù)調(diào)研(一)

一、Objective-C Runtime到底是什么東西忿檩?

簡而言之尉尾,Objective-C Runtime是一個將C語言轉(zhuǎn)化為面向?qū)ο笳Z言的擴(kuò)展。

我們將C++和Objective進(jìn)行對比燥透,雖然C++和Objective-C都是在C的基礎(chǔ)上加入面向?qū)ο蟮奶匦詳U(kuò)充而成的程序設(shè)計語言沙咏,但二者實現(xiàn)的機(jī)制差異很大。C++是基于靜態(tài)類型班套,而Objective-C是基于動態(tài)運行時類型肢藐。也就是說用C++編寫的程序編譯時就直接編譯成了可令機(jī)器讀懂的機(jī)器語言;用Objective-C編寫的程序不能直接編譯成可令機(jī)器讀懂的機(jī)器語言吱韭,而是在程序運行的時候吆豹,通過Runtime把程序轉(zhuǎn)為可令機(jī)器讀懂的機(jī)器語言。也就是說用C++編寫的程序通過編譯器直接把函數(shù)地址硬編碼進(jìn)入可執(zhí)行文件理盆;而Objective-C無法通過編譯器直接把函數(shù)地址硬編碼進(jìn)入可執(zhí)行文件痘煤,而是在程序運行的時候,利用Runtime根據(jù)條件判斷作出決定猿规。函數(shù)標(biāo)識與函數(shù)過程的真正內(nèi)容之間的關(guān)聯(lián)可以動態(tài)修改衷快。Runtime是Objective不可缺少的重要一部分。

Demo傳送門-> runtime源碼

二姨俩、Objective-C的元素認(rèn)知

2.1 id和Class

打開/Public Headers/objc.h文件可以看到如下定義:

#if!OBJC_TYPES_DEFINED/// An opaque type that represents an Objective-C class.typedefstructobjc_class*Class;/// Represents an instance of a class.structobjc_object{Class isa? OBJC_ISA_AVAILABILITY;};/// A pointer to an instance of a class.typedefstructobjc_object*id;#endif

Class是一個指向objc_class結(jié)構(gòu)體的指針蘸拔,而id是一個指向objc_object結(jié)構(gòu)體的指針,其中的isa是一個指向objc_class結(jié)構(gòu)體的指針环葵。其中的id就是我們所說的對象调窍,Class就是我們所說的類。

打開/Public Headers/runtime.h文件

objc_class的定義如下:

typedef struct objc_class *Class;

structobjc_class{

Class isa? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? OBJC_ISA_AVAILABILITY;// metaclass

#if!__OBJC2__

Class super_class? ? ? ? ? ? ? ? ? ? ? ? OBJC2_UNAVAILABLE;// 父類

constchar*name? ? ? ? ? ? ? ? ? ? ? ? ? OBJC2_UNAVAILABLE;// 類名

long version? ? ? ? ? ? ? ? ? ? ? ? ? ? ? OBJC2_UNAVAILABLE;// 類的版本信息张遭,默認(rèn)為0邓萨,可以通過runtime函數(shù)class_setVersion或者class_getVersion進(jìn)行修改、讀取

long info? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? OBJC2_UNAVAILABLE;// 類信息,供運行時期使用的一些位標(biāo)識先誉,如CLS_CLASS (0x1L) 表示該類為普通 class,其中包含實例方法和變量;CLS_META (0x2L) 表示該類為 metaclass的烁,其中包含類方法;

long instance_size? ? ? ? ? ? ? ? ? ? ? ? OBJC2_UNAVAILABLE;// 該類的實例變量大泻侄(包括從父類繼承下來的實例變量)

struct objc_ivar_list*ivars? ? ? ? ? ? ? OBJC2_UNAVAILABLE;// 該類的成員變量地址列表

struct objc_method_list**methodLists? ? OBJC2_UNAVAILABLE;// 方法地址列表,與 info 的一些標(biāo)志位有關(guān)渴庆,如CLS_CLASS (0x1L)铃芦,則存儲實例方法,如CLS_META (0x2L)襟雷,則存儲類方法;

struct objc_cache*cache? ? ? ? ? ? ? ? ? OBJC2_UNAVAILABLE;// 緩存最近使用的方法地址刃滓,用于提升效率;

struct objc_protocol_list*protocols? ? ? OBJC2_UNAVAILABLE;// 存儲該類聲明遵守的協(xié)議的列表

#endif

}

/* Use `Class` instead of `struct objc_class *` */

由以上代碼可見耸弄,類與對象的區(qū)別就是類比對象多了很多特征成員咧虎,?類也可以當(dāng)做一個objc_object來對待,也就是說類和對象都是對象计呈,分別稱作類對象(class object)和實例對象(instance object)砰诵,這樣我們就可以區(qū)別對象和類了。

isa:objc_object(實例對象)中isa指針指向的類結(jié)構(gòu)稱為class(也就是該對象所屬的類)其中存放著普通成員變量與動態(tài)方法(“-”開頭的方法)捌显;此處isa指針指向的類結(jié)構(gòu)稱為metaclass茁彭,其中存放著static類型的成員變量與static類型的方法(“+”開頭的方法)。

super_class: 指向該類的父類的指針扶歪,如果該類是根類(如NSObject或NSProxy)理肺,那么super_class就為nil。

類與對象的繼承層次關(guān)系如圖(圖片源自網(wǎng)絡(luò)):


所有的metaclass中isa指針都是指向根metaclass善镰,而根metaclass則指向自身妹萨。根metaclass是通過繼承根類產(chǎn)生的,與根class結(jié)構(gòu)體成員一致炫欺,不同的是根metaclass的isa指針指向自身眠副。

2.2 SEL

SEL是selector在Objective-C中的表示類型。selector可以理解為區(qū)別方法的ID竣稽。

typedef struct objc_selector *SEL;

objc_selector的定義如下:

struct objc_selector{

char*name;OBJC2_UNAVAILABLE;// 名稱

char*types;OBJC2_UNAVAILABLE;// 類型

};

name和types都是char類型囱怕。

2.3 IMP

終于到IMP了,它在objc.h中得定義如下:

typedef id(*IMP)(id,SEL,...);

IMP是“implementation”的縮寫毫别,它是由編譯器生成的一個函數(shù)指針娃弓。當(dāng)你發(fā)起一個消息后(下文介紹),這個函數(shù)指針決定了最終執(zhí)行哪段代碼岛宦。

2.4 Method

Method代表類中的某個方法的類型台丛。

typedef struct objc_method *Method;

objc_method的定義如下:

struct objc_method{

SEL method_name? ? ? ? ? ? ? ? ? OBJC2_UNAVAILABLE;// 方法名

char*method_types? ? ? ? ? ? ? ? OBJC2_UNAVAILABLE;// 方法類型

IMP method_imp? ? ? ? ? ? ? ? ? ? OBJC2_UNAVAILABLE;// 方法實現(xiàn)

}

方法名method_name類型為SEL,上文提到過。

方法類型method_types是一個char指針挽霉,存儲著方法的參數(shù)類型和返回值類型防嗡。

方法實現(xiàn)method_imp的類型為IMP,上文提到過侠坎。

2.5 Ivar

Ivar代表類中實例變量的類型

typedef struct objc_ivar *Ivar;

objc_ivar的定義如下:

struct objc_ivar{

char*ivar_name? ? ? ? ? ? ? ? ? OBJC2_UNAVAILABLE;// 變量名

char*ivar_type? ? ? ? ? ? ? ? ? OBJC2_UNAVAILABLE;// 變量類型

intivar_offset? ? ? ? ? ? ? ? ? OBJC2_UNAVAILABLE;// ?基地址偏移字節(jié)

#ifdef __LP64__

? ?intspace? ? ? ? ? ? ? ? ? ? ? ? OBJC2_UNAVAILABLE;// 占用空間

#endif

}

2.6 objc_property_t

objc_property_t是屬性蚁趁,它的定義如下:

typedef struct objc_property *objc_property_t;

objc_property是內(nèi)置的類型,與之關(guān)聯(lián)的還有一個objc_property_attribute_t实胸,它是屬性的attribute他嫡,也就是其實是對屬性的詳細(xì)描述,包括屬性名稱庐完、屬性編碼類型钢属、原子類型/非原子類型等。它的定義如下:

typedef struct{

constchar*name;// 名稱

constchar*value;// 值(通常是空的)

}objc_property_attribute_t;

2.7 Cache

Catch的定義如下:

typedef struct objc_cache *Cache

objc_cache的定義如下:

struct objc_cache{

unsigned int mask? ? ? ? ? ? ? ? ? OBJC2_UNAVAILABLE;

unsigned int occupied ? ? ? ? ? OBJC2_UNAVAILABLE;

Method buckets[1] ? ? ? ? ? ? ? ? OBJC2_UNAVAILABLE;

};

mask: 指定分配cache buckets的總數(shù)门躯。在方法查找中淆党,Runtime使用這個字段確定數(shù)組的索引位置。

occupied: 實際占用cache buckets的總數(shù)讶凉。

buckets: 指定Method數(shù)據(jù)結(jié)構(gòu)指針的數(shù)組宁否。這個數(shù)組可能包含不超過mask+1個元素。需要注意的是缀遍,指針可能是NULL慕匠,表示這個緩存bucket沒有被占用,另外被占用的bucket可能是不連續(xù)的域醇。這個數(shù)組可能會隨著時間而增長台谊。

objc_msgSend(下文講解)每調(diào)用一次方法后,就會把該方法緩存到cache列表中譬挚,下次的時候锅铅,就直接優(yōu)先從cache列表中尋找,如果cache沒有减宣,才從methodLists中查找方法盐须。

2.8 Catagory

這個就是我們平時所說的類別了,很熟悉吧漆腌。它可以動態(tài)的為已存在的類添加新的方法贼邓。

它的定義如下:

typedef struct objc_category *Category;

objc_category的定義如下:

struct objc_category{

char*category_name? ? ? ? ? ? ? ? ? ? ? ? ? OBJC2_UNAVAILABLE;// 類別名稱char*class_name? ? ? ? ? ? ? ? ? ? ? ? ? ? ? OBJC2_UNAVAILABLE;// 類名

struct objc_method_list*instance_methods? ? OBJC2_UNAVAILABLE;// 實例方法列表

struct objc_method_list*class_methods? ? ? ? OBJC2_UNAVAILABLE;// 類方法列表struct objc_protocol_list*protocols? ? ? ? ? OBJC2_UNAVAILABLE;// 協(xié)議列表

}

因為是入門,以上就列舉這些吧闷尿!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末塑径,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子填具,更是在濱河造成了極大的恐慌统舀,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異誉简,居然都是意外死亡碉就,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進(jìn)店門闷串,熙熙樓的掌柜王于貴愁眉苦臉地迎上來瓮钥,“玉大人,你說我怎么就攤上這事窿克】ビ梗” “怎么了毛甲?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵年叮,是天一觀的道長。 經(jīng)常有香客問我玻募,道長只损,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任七咧,我火速辦了婚禮跃惫,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘艾栋。我一直安慰自己爆存,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布蝗砾。 她就那樣靜靜地躺著先较,像睡著了一般。 火紅的嫁衣襯著肌膚如雪友题。 梳的紋絲不亂的頭發(fā)上惕它,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天耘纱,我揣著相機(jī)與錄音,去河邊找鬼菜循。 笑死,一個胖子當(dāng)著我的面吹牛申尤,可吹牛的內(nèi)容都是我干的癌幕。 我是一名探鬼主播,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼昧穿,長吁一口氣:“原來是場噩夢啊……” “哼序芦!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起粤咪,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤谚中,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體宪塔,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡磁奖,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了某筐。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片比搭。...
    茶點故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖南誊,靈堂內(nèi)的尸體忽然破棺而出身诺,到底是詐尸還是另有隱情,我是刑警寧澤抄囚,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布霉赡,位于F島的核電站,受9級特大地震影響幔托,放射性物質(zhì)發(fā)生泄漏穴亏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一重挑、第九天 我趴在偏房一處隱蔽的房頂上張望嗓化。 院中可真熱鬧,春花似錦谬哀、人聲如沸刺覆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽谦屑。三九已至,卻和暖如春劲室,著一層夾襖步出監(jiān)牢的瞬間伦仍,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工很洋, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留充蓝,地道東北人。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓喉磁,卻偏偏與公主長得像谓苟,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子协怒,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,843評論 2 354

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

  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉涝焙,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 1,715評論 0 9
  • 轉(zhuǎn)載:http://yulingtianxia.com/blog/2014/11/05/objective-c-r...
    F麥子閱讀 733評論 0 2
  • 本文詳細(xì)整理了 Cocoa 的 Runtime 系統(tǒng)的知識,它使得 Objective-C 如虎添翼孕暇,具備了靈活的...
    lylaut閱讀 800評論 0 4
  • 原文出處:南峰子的技術(shù)博客 Objective-C語言是一門動態(tài)語言仑撞,它將很多靜態(tài)語言在編譯和鏈接時期做的事放到了...
    _燴面_閱讀 1,229評論 1 5
  • 我們常常會聽說 Objective-C 是一門動態(tài)語言赤兴,那么這個「動態(tài)」表現(xiàn)在哪呢?我想最主要的表現(xiàn)就是 Obje...
    Ethan_Struggle閱讀 2,193評論 0 7