四、Runtime 概念部分 之 Class & Object

本文github地址 https://github.com/ICZhuang/Runtime 朋友們?nèi)绻矚g收藏即可,不建議轉(zhuǎn)載,筆者會(huì)不定期update文章,github 也會(huì)同步更新,喜歡就star一下吧。

除了前面介紹的三部分(Ivar/Property/Method),基礎(chǔ)的概念部分其實(shí)還應(yīng)包括 Protocol 和 Category。但筆者打算暫時(shí)放下它們。這里想先學(xué)習(xí)Class & Object的原因有以下幾點(diǎn)

  • Ivar/Property/Method 三者是我們平常開發(fā)最常見的組成部分,而且足以構(gòu)成一個(gè)完整類;
  • 關(guān)于 Ivar/Property/Method 還有一些操作函數(shù),這些函數(shù)實(shí)際是針對(duì)于 Class 或者 Object 的;
  • Protocol、 Category 和前面三者基本是差不多的學(xué)習(xí)方法;

關(guān)于 Runtime 的文章太多了,基本上都會(huì)說明三個(gè)關(guān)鍵 類對(duì)象(Class) 元類對(duì)象(Meta Class) 和實(shí)例對(duì)象(Instance),雖然可能會(huì)暈暈乎乎的,但怎么說也有點(diǎn)大概印象,那么在筆者這里只是列舉筆者認(rèn)為的關(guān)鍵點(diǎn)來幫助理解,說白了,也是方便筆者重拾對(duì)Runtime的理解。

還要說明一點(diǎn),要完全剖析 Runtime,筆者認(rèn)為看源碼最合適,奈何筆者不是C、C++大牛,這重任暫時(shí)被擱下了,所以筆者寫的文章也不會(huì)深入的太底層,層面還是來于從網(wǎng)絡(luò)文章和官方文檔加上自己實(shí)踐驗(yàn)證學(xué)習(xí)而來的。

從兩個(gè)結(jié)構(gòu)體開始說起


Runtime 中對(duì)對(duì)象的定義如下所示,是一個(gè) objc_object 結(jié)構(gòu)體,里面擁有一個(gè) Class 類型的 isa 指針

struct objc_object {
    Class isa  OBJC_ISA_AVAILABILITY;
};

但筆者理解,這里的對(duì)象不要狹隘的理解成是實(shí)例對(duì)象,因?yàn)榻酉聛眍惖淖侄我灿幸粋€(gè)isa

相信在接觸 Runtime 之初,大家都聽過這么一句話:“擁有這個(gè)isa指針的都是對(duì)象”,有這樣一個(gè)解釋我覺得很合理:’isa’其實(shí)就是 ‘is a’,這倒是挺形象的描述了這句話。。因?yàn)?,isa 指針就是指向的該對(duì)象所屬的類。

往下查找 Class 類型,它是一個(gè) objc_class 結(jié)構(gòu)體類型指針,objc_class 結(jié)構(gòu)體如下所示

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;

套路來了,這里筆者還是要假裝地提一下這個(gè)問題,方便做牽引和說明,就是:“既然對(duì)象 isa 指向的是所屬的類,怎么類里面還有一個(gè)isa?搞事情???”

無疑,類擁有了 isa 指針,那么類也是一個(gè)對(duì)象,稱為類對(duì)象,相信大家可能聽過或者已經(jīng)了解過了,它在內(nèi)存中就是一個(gè)單例對(duì)象。那既然 isa 是指向其類的指針,那類的 isa 指針如何指向?

答案是,類對(duì)象的 isa 指向的稱為元類(meta class),可以看出,元類也是 Class 類型的??梢哉f類對(duì)象的類型就是它的元類

其實(shí)結(jié)構(gòu)體 objc_object 只是定義了 Objective-C 中對(duì)象應(yīng)該長(zhǎng)什么樣,以此說明類和元類都是對(duì)象。任何繼承與NSObject的類都有一個(gè)'isa'指針,NSObject就是OC層面的‘objc_object’。

內(nèi)存布局


實(shí)例對(duì)象也是對(duì)象,難道它的實(shí)例變量就只有一個(gè)isa?那繼承NSObject后自己定義的實(shí)例變量放在哪里?

這里要先停一下了,推薦大家先看一下這篇博客,了解一個(gè)對(duì)象在內(nèi)存的布局和它與類之間的關(guān)系,將會(huì)有大幫助 因?yàn)椴幌雽懲瑯拥钠?,這里放上博客鏈接 http://www.cnblogs.com/csutanyu/archive/2011/12/12/Objective-C_memory_layout.html

這里附上筆者理解后做的關(guān)于RTModel的內(nèi)存布局,就是指針指來指去。(不知Heap位置放對(duì)了沒有,因?yàn)椴恢纁lass對(duì)象都放在哪,Heap基于筆者對(duì)C的理解)

image-01
image-01

我們定義的那些類,運(yùn)行時(shí)候加載到內(nèi)存中, 將類中定義的對(duì)象方法存到方法列表的 methodLists 字段中,成員變量存到 ivars 中,遵循的協(xié)議存到 protocols 中,這些都是 objc_class 結(jié)構(gòu)體就已經(jīng)定義的

實(shí)例對(duì)象 instance 可以在內(nèi)存空間允許的情況下創(chuàng)建多個(gè),實(shí)例對(duì)象依據(jù)類(class)對(duì)象而生。但實(shí)例對(duì)象存放的是實(shí)例變量(當(dāng)然包括了父類聲明的成員變量,父類的在前,子類的在后),因?yàn)閕var才是各個(gè)實(shí)例對(duì)象不同的地方,像方法這種共用的就放在類中,否則開辟一個(gè)實(shí)例變量就拷貝一份方法列表,那內(nèi)存會(huì)吃不消的。

調(diào)用對(duì)象方法,就是給實(shí)例對(duì)象發(fā)送消息,通過在它的類中的方法列表 methodLists 找到方法并執(zhí)行。

接著可以說說元類(meta class)了,如上面所述,類(class)的isa指向的就是元類。而且元類的結(jié)構(gòu)跟類的結(jié)構(gòu)是一樣的。只是在元類的方法列表 methodLists 中,存放的是類中定義的 類方法,而類中的 methodLists 存放的是對(duì)象方法。當(dāng)調(diào)用類方法的時(shí)候,通過在元類中找到方法并執(zhí)行。還有關(guān)于 Cache,是關(guān)于方法的緩存,再深究的話就到講實(shí)現(xiàn)上面了,筆者還沒研究那么深呢,哈哈,原諒。

image-02
image-02

可以發(fā)現(xiàn),元類既然也是 Class 類型,那它也應(yīng)該是類對(duì)象,isa指向它的類。那最終isa指向誰呢?這里筆者不負(fù)責(zé)任的說,上面推薦的博客最下方的圖已經(jīng)比較形象清晰的了。。 或許你還見過那個(gè)文檔中拷出來的圖,跟博客中的是一樣的意思,比如這篇博客也有極大幫助http://blog.csdn.net/wzzvictory/article/details/8592492

總結(jié):


  • Runtime 中對(duì)對(duì)象的概念 和我們開發(fā)中念叨的實(shí)例對(duì)象要分清,這里只是OC對(duì)對(duì)象的宏觀的定義;
  • 實(shí)例對(duì)象存放著各自的實(shí)例變量,但共用 class 對(duì)象,實(shí)例對(duì)象的 isa 指向它的 class 對(duì)象;
  • class 的 isa 指向它的元類對(duì)象 meta class,meta class的 isa 都指向 NSObject meta class;
  • class 的 super_class 指向其父類的 class,NSObject class的super_class 指向0x0;
  • meta class 的 super_class 指向其父類的 meta class, 但 NSObject meta class 的 super_class 指向它自己的類對(duì)象(class);
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 2,043評(píng)論 0 9
  • 首先說明,這篇文章幾乎都是抄錄的別人的博客,簡(jiǎn)書文章,在此總結(jié),只是為了方便記憶和以后閱讀,如果有什么失禮的地方,...
    LiYaoPeng閱讀 5,339評(píng)論 1 14
  • 這篇文章完全是基于南峰子老師博客的轉(zhuǎn)載 這篇文章完全是基于南峰子老師博客的轉(zhuǎn)載 這篇文章完全是基于南峰子老師博客的...
    西木閱讀 30,886評(píng)論 33 466
  • 原文出處:南峰子的技術(shù)博客 Objective-C語言是一門動(dòng)態(tài)語言,它將很多靜態(tài)語言在編譯和鏈接時(shí)期做的事放到了...
    _燴面_閱讀 1,407評(píng)論 1 5
  • Objective-C語言是一門動(dòng)態(tài)語言,他將很多靜態(tài)語言在編譯和鏈接時(shí)期做的事情放到了運(yùn)行時(shí)來處理。這種動(dòng)態(tài)語言...
    tigger丨閱讀 1,589評(píng)論 0 8

友情鏈接更多精彩內(nèi)容