打開<objc/NSObject>html
NSObject含有一個Class類型的isa指針。ios
@interface NSObject <NSObject> { Class isa OBJC_ISA_AVAILABILITY; }
objc/objc.hspa
struct objc_object { Class isa OBJC_ISA_AVAILABILITY; };
在XCode中按Shift + Command + O打開文件搜索框,而後輸入NSObject.h和objc.h,指針
能夠看到以下的內容code
typedef struct objc_class *Class;
所以OC中的Class 也就是 一個結構體objc_class的指針htm
再在runtime.h中看objc_class的定義對象
struct objc_class { Class isa OBJC_ISA_AVAILABILITY; #if !__OBJC2__ Class super_class OBJC2_UNAVAILABLE; const char *name OBJC2_UNAVAILABLE; long version OBJC2_UNAVAILABLE; long info OBJC2_UNAVAILABLE; long instance_size OBJC2_UNAVAILABLE; struct objc_ivar_list *ivars OBJC2_UNAVAILABLE; struct objc_method_list **methodLists OBJC2_UNAVAILABLE; struct objc_cache *cache OBJC2_UNAVAILABLE; struct objc_protocol_list *protocols OBJC2_UNAVAILABLE; #endif } OBJC2_UNAVAILABLE;
objc_class是一個結構體,包含一個開發
Class類型的isa,io
父類的指針Class super_class,class
類名 name,
struct objc_ivar_list *ivars 成員變量的列表
struct objc_method_list **methodLists 方法列表
struct objc_cache *cache
struct objc_protocol_list *protocols 協議列表
由於類也是一個對象,那它也必須是另外一個類的實例,這個類就是元類 (metaclass)。
一個接收者對象接收到一個消息時,它會根據isa指針去查找可以響應這個消息的對象。 優先去cache中查找,若是cache沒有,纔去methodLists中查找方法。這樣,對於那些常常用到的方法的調用,但提升了調用的效率。若是methodlists中沒有,會去父類中繼續查找。
若是查到根類Root Class仍然沒有,那就啓動消息轉發機制。
類方法也是相似的原理。
消息的轉發分爲兩大階段。
第一階段先徵詢接收者,所屬的類,看其是否能動態添加方法,以處理當前這個「未知的選擇子」(unknown selector),這叫作「動態方法解析」(dynamic method resolution)。
第二階段涉及「完整的消息轉發機制」。若是運行期系統已經把第一階段執行完了,那麼接收者本身就沒法再以動態新增方法的手段來響應包含該選擇子的消息了。此時,運行期系統會請求接受者以其餘手段來處理與消息相關的方法調用。這又細分爲兩小步。首先,請接受者看看有沒有其餘對象處理這條消息。如有,則運行期系統會把消息轉給那個對象,因而消息轉發過程結束,一塊兒如常。若沒有「備援的接收者」,則啓動完整的消息轉發機制,運行期系統會把於消息有關的所有細節都封裝到NSInvocation對象中,再給接收者最後一次機會,令其設法解決當前還未處理的這條消息。
參考資料
類的本質-類對象
http://www.jianshu.com/p/374b570e1920
iOS開發探索-Runtime原理解讀及實踐
http://www.jianshu.com/p/462b88edbe5c
深刻理解Objective-C消息轉發機制
http://www.cocoachina.com/ios/20160830/17424.html