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

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

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

我們將C++和Objective進(jìn)行對比,雖然C++和Objective-C都是在C的基礎(chǔ)上加入面向?qū)ο蟮奶匦詳U充而成的程序設(shè)計語言,但二者實現(xiàn)的機制差異很大。C++是基于靜態(tài)類型,而Objective-C是基于動態(tài)運行時類型。也就是說用C++編寫的程序編譯時就直接編譯成了可令機器讀懂的機器語言;用Objective-C編寫的程序不能直接編譯成可令機器讀懂的機器語言,而是在程序運行的時候,通過Runtime把程序轉(zhuǎn)為可令機器讀懂的機器語言。也就是說用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)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

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

友情鏈接更多精彩內(nèi)容