網(wǎng)上查看了一些runtime的資料, 關(guān)于runtime是什么?這里想用自己的理解,簡單點(diǎn)說:runtime是一套基于C語言的動(dòng)態(tài)運(yùn)行時(shí)機(jī)制. 這套機(jī)制實(shí)現(xiàn)了objective-C中一系列面向?qū)ο蟮幕居梅? 比如類的定義,對(duì)象創(chuàng)建,方法調(diào)用.總之,它就是介于C語言和objective-C之前的一個(gè)抽象層.OK,就講這么多.objective-C是一門動(dòng)態(tài)的語言, 我想這里應(yīng)該是最好的體現(xiàn). 所有的方法,在執(zhí)行之前,你都不知道,它的實(shí)現(xiàn)到底在哪里. 在運(yùn)行的時(shí)候,你可以動(dòng)態(tài)添加方法,實(shí)例變量,重定向方法的實(shí)現(xiàn)等.
在objective-C中我們可以通過三種方式來與runtime進(jìn)行交流.
- 當(dāng)我們編寫純原生的objective-C代碼時(shí), 當(dāng)這些代碼經(jīng)過編譯,鏈接, 載入內(nèi)存運(yùn)行的時(shí)候, 會(huì)自動(dòng)的經(jīng)過runtime這套機(jī)制處理. 從我們創(chuàng)建對(duì)象到調(diào)用方法.都會(huì)最終映射到runtime上去處理.因?yàn)镃語言不具備這種能力.runtime的作用就是這.彌補(bǔ)C的天生缺陷.而這一切,都是對(duì)程序員透明的, 自動(dòng)的.
- 通過objective-C的基礎(chǔ)類庫Foundation中NSObject提供的方法.由于大多數(shù)類最終都是繼承NSObject的,所以大多數(shù)類都可以通過使用NSObject提供的方法與runtime交流. 可以到NSObject.h里面去看看哪些方法.
- 直接使用runtime提供的函數(shù).
所有的runtime函數(shù)都在這里:https://developer.apple.com/documentation/objectivec/objective_c_runtime?language=objc
- 下面來看看objective-C中使用最多的對(duì)象到底是什么?
在objective-C中所有的類都繼承自NSObject類.
@interface NSObject <NSObject> {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-interface-ivars"
Class isa OBJC_ISA_AVAILABILITY;
#pragma clang diagnostic pop
}
這里注意區(qū)分類與對(duì)象的區(qū)分. 類是一種邏輯描述, 是抽象的, 而對(duì)象是在內(nèi)存中確實(shí)存在的,是具象的.定義一個(gè)類,只是在抽象層上描述一個(gè)對(duì)象是怎么樣的.我們創(chuàng)建對(duì)象的時(shí)候,根據(jù)類(對(duì)象的描述)來分配內(nèi)存,初始化最后得到了一個(gè)對(duì)象. 在objective-C中我們總是根據(jù)一個(gè)類的定義去創(chuàng)建該類所描述的對(duì)象.
-
NSObject對(duì)象
根據(jù)NSObject類,創(chuàng)建一個(gè)NSObject對(duì)象, 該對(duì)象(對(duì)象所屬的類)有一個(gè)成員變量{Class isa;}. 下面我們看看,Class是什么?1.1 Class 是什么?
Class是個(gè)結(jié)構(gòu)體指針.詳細(xì)定義見代碼1.1
代碼1.1
/// An opaque type that represents an Objective-C class.
typedef struct objc_class *Class;
struct objc_class {
Class _Nonnull isa OBJC_ISA_AVAILABILITY;
#if !__OBJC2__
Class _Nullable super_class OBJC2_UNAVAILABLE;
const char * _Nonnull name OBJC2_UNAVAILABLE;
long version OBJC2_UNAVAILABLE;
long info OBJC2_UNAVAILABLE;
long instance_size OBJC2_UNAVAILABLE;
struct objc_ivar_list * _Nullable ivars OBJC2_UNAVAILABLE;
struct objc_method_list * _Nullable * _Nullable methodLists OBJC2_UNAVAILABLE;
struct objc_cache * _Nonnull cache OBJC2_UNAVAILABLE;
struct objc_protocol_list * _Nullable protocols OBJC2_UNAVAILABLE;
#endif
} OBJC2_UNAVAILABLE;
/* Use `Class` instead of `struct objc_class *` */
忽略掉所有的預(yù)編譯指令, 回到代碼上來, 暫且就認(rèn)為Class是個(gè)結(jié)構(gòu)體指針.
接著上面的1說:我們知道內(nèi)存中的一個(gè)NSObject對(duì)象,里面有個(gè)isa指針變量,它指向一個(gè)結(jié)構(gòu)體.OK , 指針不太明白,暫且這么理解:也就是說根據(jù)isa里面提供的值(其實(shí)就是一個(gè)地址),我們可以在內(nèi)存中找到一個(gè)struct Class 類型的結(jié)構(gòu)體. 具體是什么樣的,請看代碼1.1
- 下面我們看看,這個(gè)isa所指向的結(jié)構(gòu)體具體是什么?
isa指針:指向該對(duì)象所屬類型的類型對(duì)象(Class Object)溺蕉。在Objective-C中具篇,類也是用對(duì)象來表示的固翰,而類的isa指針指向它的metaclass(存儲(chǔ)靜態(tài)成員變量和類方法)。
super_class指針:指向父類藤巢。
name:類名稱。
version:類的版本信息。
info:運(yùn)行期使用的標(biāo)志位葬项,比如0x1(CLS_CLASS)表示該類為普通class,0x2(CLS_META)表示該類為 metaclass迹蛤。
instance_size:實(shí)例大小民珍,即內(nèi)存所占空間。
ivars:指向成員變量列表的指針盗飒。
methodLists:根據(jù)標(biāo)志位的不同可能指向不同嚷量,比如可能指向?qū)嵗椒斜恚蛘咧赶蝾惙椒斜怼?br> cache:因?yàn)镺bjective-C的消息轉(zhuǎn)發(fā)需要查找dispatch table甚至可能需要遍歷繼承體系逆趣,所以緩存最近使用的方法蝶溶。
protocols:類需要遵守的協(xié)議。
由NSObject對(duì)象的isa指針指向的結(jié)構(gòu)體可知,這個(gè)結(jié)構(gòu)體描述的是關(guān)于NSObject類的信息, 可稱作objc_class 結(jié)構(gòu)體.它描述了NSObject類的成員列表,方法列表,所遵守的協(xié)議列表等關(guān)于該類的信息.
在objc_class結(jié)構(gòu)體中,也有一個(gè)isa指針,指向一個(gè)和自己相同類型的結(jié)構(gòu)體. 這其實(shí)不難理解, 對(duì)象相關(guān)的邏輯描述信息,存放在該對(duì)象所屬類的那個(gè)結(jié)構(gòu)體中.也即是objc_class結(jié)構(gòu)體中. 但是在objective-C中, 類本身也是一個(gè)特殊的對(duì)象,所以其中也有一個(gè)isa指針. 或者說objc_class中也有一個(gè)isa指針, 我們也可以把它當(dāng)做一個(gè)對(duì)象來看待.
-
objc_class中的isa指針又指向哪里呢?
指向該類的元類(metaclass).我們可以簡單把objc_class看成是其成員變量isa指針?biāo)赶蛟惖膶?shí)例. 同理,元類是描述這個(gè)類的具體信息的,屬于更高一層的抽象.
到這里已經(jīng)差不多了.metaclass 中的isa指針又指向哪里呢, 答:指向根元類.根元類的isa指向自己.也就是說所有的對(duì)象,類,元類的最終歸宿都是跟元類.
實(shí)例 類 元類
好吧, 我認(rèn)為把我所知道的都寫明白了. 關(guān)于消息的處理轉(zhuǎn)發(fā), 以及
runtime提供的一些函數(shù)的具體使用.下一篇再說.
引用:http://blog.csdn.net/oqqquzi1234567/article/details/43268947