Runtime底層原理--Runtime簡介、函數註釋

Runtime底層原理

Runtime官方文檔介紹直通車

擴展:編譯時
看到運行時就會想到編譯時,編譯時主要是將源代碼翻譯成可識別的機器語言,如果編譯時類型檢查等翻譯過程中發現語法分析之類有錯誤會給出相應的提示。比如OC,swift,Java等高級語言的可讀性比較強,但是一般不會被機器直接識別,所以需要將他們編譯成機器語言(彙編等),轉爲二進制

Runtime簡介

在 Objective-C 中,消息是直到運行的時候才和方法實現綁定的。編譯器會把一個消息表達式,

[receiver message]

轉換成一個對消息函數objc_msgSend的調用。該函數有兩個主要參數:消息接收者和消息對應的方法——也就是方法編號(name),發送消息時候,通過sel找到函數實現的指針imp

objc_msgSend(receiver, selector)

編譯器將自動插入調用該消息函數的代碼,同時接收消息中的任意數目的參數:

objc_msgSend(receiver, selector, arg1, arg2, ...)

該消息函數做了動態綁定所需要的一切:

  • 它首先找到選標所對應的方法實現。因爲不同的類對同一方法可能會有不同的實現,所以找到的方法實現依賴於消息接收者的類型。
  • 然後將消息接收者對象(指向消息接收者對象的指針)以及方法中指定的參數傳給找到的方法實現。
  • 最後,將方法實現的返回值作爲該函數的返回值返回。

消息機制的關鍵在於編譯器爲類和對象生成的結構。每個類的結構中至少包括兩個基本元素:

  • 指向父類的指針。
  • 類的方法表。方法表將方法選標和該類的方法實現的地址關聯起來。

和運行時系統的交互

Objective-C 程序有三種途徑和運行時系統交互:

  • 通過Objective-C源代碼
    大部分情況下,運行時系統在後臺自動運行,當編譯Objective-C類和方法時,編譯器爲實現語言動態特性將自動創建一些數據結構和函數。運行時系統的主要功能就是根據源代碼中的表達式發送消息。
  • 通過Foundation框架中 NSObject 的方法
    Cocoa程序中絕大部分類都是NSObject類的子類,所以大部分都繼承了NSObject類的方法,因而繼承 了NSObject的行爲。然而,某些情況下, NSObject類僅僅定義了完成某件事情的模板,而沒有提供所有需要的代碼(比如 description 方法)。某些 NSObject 的方法只是簡單地從運行時系統中獲得信息,從而允許對象進行一定程度的自我檢查(比如methodForSelector方法返回指定方法實現的地址)。
  • 通過調用運行時系統函數
    直接調用運行時系統給我們提供的API接口

Runtime函數註釋


// 1.objc_xxx系列函數  宏觀使用,如類與協議的空間分配,註冊,註銷等操作
// 函數名稱     函數作用
objc_getClass     獲取Class對象
objc_getMetaClass     獲取MetaClass對象
objc_allocateClassPair     分配空間,創建類(僅在 創建之後,註冊之前 能夠添加成員變量)
objc_registerClassPair     註冊一個類(註冊後方可使用該類創建對象)
objc_disposeClassPair     註銷某個類
objc_allocateProtocol     開闢空間創建協議
objc_registerProtocol     註冊一個協議
objc_constructInstance     構造一個實例對象(ARC下無效)
objc_destructInstance     析構一個實例對象(ARC下無效)
objc_setAssociatedObject     爲實例對象關聯對象
objc_getAssociatedObje*ct     獲取實例對象的關聯對象
objc_removeAssociatedObjects     清空實例對象的所有關聯對象

// 2.class_xxx系列函數   類的內部,如實例變量,屬性,方法,協議等相關問題
函數名稱     函數作用
class_addIvar     爲類添加實例變量
class_addProperty     爲類添加屬性
class_addMethod     爲類添加方法
class_addProtocol     爲類遵循協議
class_replaceMethod     替換類某方法的實現
class_getName     獲取類名
class_isMetaClass     判斷是否爲元類
objc_getProtocol     獲取某個協議
objc_copyProtocolList     拷貝在運行時中註冊過的協議列表
class_getSuperclass     獲取某類的父類
class_setSuperclass     設置某類的父類
class_getProperty     獲取某類的屬性
class_getInstanceVariable     獲取實例變量
class_getClassVariable     獲取類變量
class_getInstanceMethod     獲取實例方法
class_getClassMethod     獲取類方法
class_getMethodImplementation     獲取方法的實現
class_getInstanceSize     獲取類的實例的大小
class_respondsToSelector     判斷類是否實現某方法
class_conformsToProtocol     判斷類是否遵循某協議
class_createInstance     創建類的實例
class_copyIvarList     拷貝類的實例變量列表
class_copyMethodList     拷貝類的方法列表
class_copyProtocolList     拷貝類遵循的協議列表
class_copyPropertyList     拷貝類的屬性列表

// 3.object_xxx系列函數   對象的角度,如實例變量
函數名稱     函數作用
object_copy     對象copy(ARC無效)
object_dispose     對象釋放(ARC無效)
object_getClassName     獲取對象的類名
object_getClass     獲取對象的Class
object_setClass     設置對象的Class
object_getIvar     獲取對象中實例變量的值
object_setIvar     設置對象中實例變量的值
object_getInstanceVariable     獲取對象中實例變量的值 (ARC中無效,使用object_getIvar)
object_setInstanceVariable     設置對象中實例變量的值 (ARC中無效,使用object_setIvar)

// 4.method_xxx系列函數   方法內部,如方法的參數及返回值類型和方法的實現
函數名稱     函數作用
method_getName     獲取方法名
method_getImplementation     獲取方法的實現
method_getTypeEncoding     獲取方法的類型編碼
method_getNumberOfArguments     獲取方法的參數個數
method_copyReturnType     拷貝方法的返回類型
method_getReturnType     獲取方法的返回類型
method_copyArgumentType     拷貝方法的參數類型
method_getArgumentType     獲取方法的參數類型
method_getDescription     獲取方法的描述
method_setImplementation     設置方法的實現
method_exchangeImplementations     替換方法的實現

// 5.property_xxx系列函數   屬性*內部,如屬性的特性等
函數名稱     函數作用
property_getName     獲取屬性名
property_getAttributes     獲取屬性的特性列表
property_copyAttributeList     拷貝屬性的特性列表
property_copyAttributeValue     拷貝屬性中某特性的值

// 6.protocol_xxx系列函數 協議相關
函數名稱     函數作用
protocol_conformsToProtocol     判斷一個協議是否遵循另一個協議
protocol_isEqual     判斷兩個協議是否一致
protocol_getName     獲取協議名稱
protocol_copyPropertyList     拷貝協議的屬性列表
protocol_copyProtocolList     拷貝某協議所遵循的協議列表
protocol_copyMethodDescriptionList     拷貝協議的方法列表
protocol_addProtocol     爲一個協議遵循另一協議
protocol_addProperty     爲協議添加屬性
protocol_getProperty     獲取協議中的某個屬性
protocol_addMethodDescription     爲協議添加方法描述
protocol_getMethodDescription     獲取協議中某方法的描述

// 7.ivar_xxx 系列函數  實例變量相關
函數名稱     函數作用
ivar_getName     獲取Ivar名稱
ivar_getTypeEncoding     獲取類型編碼
ivar_getOffset     獲取偏移量

// 8.sel_xxx系列函數   方法編號相關
函數名稱     函數作用
sel_getName     獲取名稱
sel_getUid     註冊方法
sel_registerName     註冊方法名
sel_isEqual     判斷方法是否相等

// 9.imp_xxx系列函數   方法實現相關
函數名稱     函數作用
imp_implementationWithBlock     通過代碼塊創建IMP
imp_getBlock     獲取函數指針中的代碼塊
imp_removeBlock     移除IMP中的代碼塊

如果想繼續探究Runtime底層原理,下篇是Runtime源碼分析,包括動態方法解析和消息轉發。
該文章爲記錄本人的學習路程,希望能夠幫助大家,也歡迎大家點贊留言交流!!!文章地址https://www.jianshu.com/p/eddc9bdb46ea

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章