一.isa指針
要認識什么是isa指針,我們得先明確一點:
在Objective-C中,任何類的定義都是對象。類和類的實例(對象)沒有任何本質上的區別。任何對象都有isa指針。
那么什么是類呢?在xcode中用快捷鍵Shift+Cmd+O 打開文件objc.h 能看到類的定義:
可以看出:
Class 是一個 objc_class 結構類型的指針, id是一個 objc_object 結構類型的指針.
我們再來看看 objc_class 的定義:
稍微解釋一下各個參數的意思:
isa:是一個Class 類型的指針. 每個實例對象有個isa的指針,他指向對象的類,而Class里也有個isa的指針, 指向meteClass(元類)。元類保存了類方法的列表。當類方法被調用時,先會從本身查找類方法的實現,如果沒有,元類會向他父類查找該方法。同時注意的是:元類(meteClass)也是類,它也是對象。元類也有isa指針,它的isa指針最終指向的是一個根元類(root meteClass).根元類的isa指針指向本身,這樣形成了一個封閉的內循環。
super_class:父類,如果該類已經是最頂層的根類,那么它為NULL。
version:類的版本信息,默認為0
info:供運行期使用的一些位標識。
instance_size:該類的實例變量大小
ivars:成員變量的數組
再來看看各個類實例變量的繼承關系:
每一個對象本質上都是一個類的實例。其中類定義了成員變量和成員方法的列表。對象通過對象的isa指針指向類。
每一個類本質上都是一個對象,類其實是元類(meteClass)的實例。元類定義了類方法的列表。類通過類的isa指針指向元類。
所有的元類最終繼承一個根元類,根元類isa指針指向本身,形成一個封閉的內循環。
二.runtime 機制
runtime:指一個程序在運行(或者在被執行)的狀態。也就是說,當你打開一個程序使它在電腦上運行的時候,那個程序就是處于運行時刻。在一些編程語言中,把某些可以重用的程序或者實例打包或者重建成為“運行庫"。這些實例可以在它們運行的時候被連接或者被任何程序調用。
objective-c中runtime:是一套比較底層的純C語言API, 屬于1個C語言庫, 包含了很多底層的C語言API。 在我們平時編寫的OC代碼中, 程序運行過程時, 其實最終都是轉成了runtime的C語言代碼。
runtime的應用:
1.動態創建一個類(比如KVO的底層實現)
2.動態地為某個類添加屬性\方法, 修改屬性值\方法
3.遍歷一個類的所有成員變量(屬性)\所有方法
實質上,以上的是通過相關方法來獲取對象或者類的isa指針來實現的。
相關函數
1.?? 增加
增加函數:class_addMethod
增加實例變量:class_addIvar
增加屬性:@dynamic標簽,或者class_addMethod,因為屬性其實就是由getter和setter函數組成
增加Protocol:class_addProtocol (說實話我真不知道動態增加一個protocol有什么用,-_-!!)
2. ?獲取
獲取函數列表及每個函數的信息(函數指針、函數名等等):class_getClassMethod method_getName ...
獲取屬性列表及每個屬性的信息:class_copyPropertyList property_getName
獲取類本身的信息,如類名等:class_getName class_getInstanceSize
獲取變量列表及變量信息:class_copyIvarList
獲取變量的值
3.? ? 替換
將實例替換成另一個類:object_setClass
替換類方法的定義:class_replaceMethod
4.其他常用方法:
交換兩個方法的實現:method_exchangeImplementations.
設置一個方法的實現:method_setImplementation.