Runtime執行時機制簡單總結

2021-07-22 10:35:51 字數 3261 閱讀 8711

/*

什麼是runtime(執行時機制):

*/ objective-c是基於c語言加入了物件導向特性和訊息**機制的動態語言,這意味著它不僅需要乙個編譯器,還需要runtime系統來動態建立類和物件,進行訊息傳送和**。objc 從三種不同的層級上與 runtime 系統進行互動,分別是通過 objective-c 源**,通過 foundation 框架的nsobject類定義的方法,通過對 runtime 函式的直接呼叫。

1.runtime是一套比較底層的純c語言api, 屬於1個c語言庫, 包含了很多底層的c語言api。

2.平時編寫的oc**, 在程式執行過程中, 其實最終都是轉成了runtime的c語言**, runtime算是oc的幕後工作者

/*

runtime的作用:

*/runtime是屬於oc的底層, 可以進行一些非常底層的操作(用oc是無法實現的)。

1.在程式執行過程中, 動態建立乙個類(比如kvo的底層實現)

2.在程式執行過程中, 動態地為某個類新增屬性\方法, 修改屬性值\方法

3.遍歷乙個類的所有成員變數(屬性)\所有方法

* nscoding(歸檔和解檔, 利用runtime遍歷模型物件的所有屬性)

* 字典 --> 模型 (利用runtime遍歷模型物件的所有屬性, 根據屬性名從字典中取出對應的值, 設定到模型的屬性上)

* kvo(利用runtime動態產生乙個類)

* 用於封裝框架(想怎麼改就怎麼改)

/*

runtime資料結構:

*/在objective-c中,使用[receiver message]語法並不會馬上執行receiver物件的message方法的**,而是向receiver傳送一條message訊息,這條訊息可能由receiver來處理,也可能由**給其他物件來處理,也有可能假裝沒有接收到這條訊息而沒有處理。其實[receiver message]被編譯器轉化為:

id objc_msgsend ( id self, sel op, ... );
下面簡單介紹runtime中重要的資料結構:

sel

表示方法選擇器。其實它就是對映到方法的c字串,你可以通過objc編譯器命令@selector()或者runtime系統的sel_registername函式來獲取乙個sel型別的方法選擇器。

id id是通用型別指標,能夠表示任何物件。id其實就是乙個指向objc_object結構體指標,它包含乙個class isa成員,根據isa指標就可以順藤摸瓜找到物件所屬的類。

class

class表示物件所屬的類。可以檢視到class其實就是乙個objc_class結構體指標。在物件導向設計中,一切都是物件,class在設計中本身也是乙個物件。

method

method表示類中的某個方法。其實method就是乙個指向objc_method結構體指標,它儲存了方法名(method_name)、方法型別(method_types)和方法實現(method_imp)等資訊。

ivar

ivar表示類中的例項變數。ivar其實就是乙個指向objc_ivar結構體指標,它包含了變數名(ivar_name)、變數型別(ivar_type)等資訊。

imp

imp本質上就是乙個函式指標,指向方法的實現。當你向某個物件傳送一條資訊,可以由這個函式指標來指定方法的實現,它最終就會執行那段**,這樣可以繞開訊息傳遞階段而去執行另乙個方法實現。

cache

cache主要用來快取。cache其實就是乙個儲存method的鍊錶,主要是為了優化方法呼叫的效能。當呼叫方法時,優先在cache查詢,如果沒有找到,再到methodlists查詢。

/* runtime訊息傳送:

*/前面從objc_msgsend作為入口,逐步深入分析runtime的資料結構,了解每個資料結構的作用和它們之間關係後,我們正式轉入訊息傳送這個正題。

objc_msgsend函式

在前面已經提過,當某個物件使用語法[receiver message]來呼叫某個方法時,其實[receiver message]被編譯器轉化為:

id objc_msgsend ( id self, sel op, ... );
現在讓我們看一下objc_msgsend它具體是如何傳送訊息:

1.首先根據receiver物件的isa指標獲取它對應的class

2.優先在class的cache查詢message方法,如果找不到,再到methodlists查詢

3.如果沒有在methodlists找到,再到super_class查詢

4.一旦找到message這個方法,就執行它實現的imp。

/*

方法解析與訊息**:

*/[receiver message]呼叫方法時,如果在message方法在receiver物件的類繼承體系中沒有找到方法,那怎麼辦?一般情況下,程式在執行時就會crash掉,丟擲 unrecognized selector sent to …類似這樣的異常資訊。但在丟擲異常之前,還有三次機會按以下順序讓你拯救程式。

1.method resolution

2.fast forwarding

3.normal forwarding

/*

三種方法的選擇:

*/runtime提供三種方式來將原來的方法實現代替掉,那該怎樣選擇它們呢?

1.method resolution:由於method resolution不能像訊息**那樣可以交給其他物件來處理,所以只適用於在原來的類中代替掉。

2.fast forwarding:它可以將訊息處理**給其他物件,使用範圍更廣,不只是限於原來的物件。

3.normal forwarding:它跟fast forwarding一樣可以訊息**,但它能通過nsinvocation物件獲取更多訊息傳送的資訊,例如:target、selector、arguments和返回值等資訊。

/*

method swizzling:

*/就是在執行時將乙個方法的實現代替為另乙個方法的實現。如果能夠利用好這個技巧,可以寫出簡潔、有效且維護性更好的**。

總結:雖然在平時專案不是經常用到objective-c的runtime特性,但當你閱讀一些ios開源專案時,你就會發現很多時候都會用到。所以深入理解objective-c的runtime資料結構、訊息**機制有助於你更容易地閱讀和學習開源專案。

runtime 執行時機制

首先,第乙個問題,1 runtime實現的機制是什麼,怎麼用,一般用於幹嘛?這個問題我就不跟大家繞彎子了,直接告訴大家,runtime是一套比較底層的純c語言api,屬於1個c語言庫,包含了很多底層的c語言api。在我們平時編寫的oc 中,程式執行過程時,其實最終都是轉成了runtime的c語言 r...

runtime 執行時機制

必備常識 1.ivar 成員變數 2.method 成員方法相關應用 1.nscoding 歸檔和解檔,利用runtime遍歷模型物件的所有屬性 2.字典 模型 利用runtime遍歷模型物件的所有屬性,根據屬性名從字典中取出對應的值,設定到模型的屬性上 3.kvo 利用runtime動態產生乙個類...

runtime 執行時機制

runtime 執行時機制 一 runtime是什麼 1 runtime是乙個全動態語言,是基於c語言的庫,裡面包含了很多底層的c語言函式。2 平時編寫的oc 在程式執行過程中,其實最終都是轉成了runtime的c語言 runtime算是oc方法的底層實現,換句話說oc的實現也就是runtime的底...