OC(Objective-C)是如何實(shí)現(xiàn)面向?qū)ο蟮模?/h2>

OC(Objective-C) 實(shí)現(xiàn)面向?qū)ο笕筇匦裕ǚ庋b、繼承、多態(tài))的方式,其核心在于 C語(yǔ)言 + Runtime(運(yùn)行時(shí)機(jī)制)

下面我們來(lái)詳細(xì)拆解OC是如何實(shí)現(xiàn)面向?qū)ο蟮摹?/p>


核心思想:從 C 結(jié)構(gòu)體到 OC 對(duì)象

本質(zhì)上,每一個(gè) OC 對(duì)象(如 NSObject *obj)都是一個(gè)指向結(jié)構(gòu)體的指針。

  1. 封裝

    • 實(shí)現(xiàn)方式:通過(guò) @interface@implementation 來(lái)實(shí)現(xiàn)。
    • 底層原理:每個(gè) Objective-C 類在編譯后,都會(huì)對(duì)應(yīng)一個(gè) C 語(yǔ)言的結(jié)構(gòu)體(struct)。這個(gè)結(jié)構(gòu)體的第一個(gè)成員通常是 Class isa,它指向類的元數(shù)據(jù)(類對(duì)象),這是運(yùn)行時(shí)機(jī)制的基石。

    示例:
    當(dāng)你定義一個(gè)類 Person

    // Person.h (接口聲明 - 封裝)
    @interface Person : NSObject
    {
        @private
        NSString *_name; // 實(shí)例變量(Ivar)
    }
    @property (nonatomic, copy) NSString *name; // 屬性(自動(dòng)生成getter/setter)
    - (void)sayHello; // 方法聲明
    @end
    

    底層近似結(jié)構(gòu)(概念上):

    struct Person_IMPL {
        Class isa;        // 繼承自NSObject,所以第一個(gè)成員是isa
        NSString *_name;  // 封裝在結(jié)構(gòu)體中的實(shí)例變量
    };
    
    • @public, @protected, @private 關(guān)鍵字用于控制實(shí)例變量的訪問(wèn)權(quán)限,實(shí)現(xiàn)了數(shù)據(jù)隱藏。
    • @property 編譯器會(huì)自動(dòng)生成對(duì)應(yīng)的 gettersetter 方法,這些方法就是對(duì)內(nèi)部實(shí)例變量進(jìn)行安全訪問(wèn)的接口,進(jìn)一步加強(qiáng)了封裝性。
  2. 繼承

    • 實(shí)現(xiàn)方式:通過(guò) :父類名 的語(yǔ)法實(shí)現(xiàn)。
    • 底層原理結(jié)構(gòu)體的內(nèi)存布局。子類對(duì)應(yīng)的結(jié)構(gòu)體,其內(nèi)存布局的第一個(gè)部分就是父類的結(jié)構(gòu)體。這就是為什么子類可以訪問(wèn)父類的屬性和方法,因?yàn)閺膬?nèi)存角度看,子類對(duì)象開(kāi)頭就是一個(gè)完整的父類對(duì)象。

    示例:

    @interface Student : Person
    @property (nonatomic, copy) NSString *school;
    @end
    

    底層近似結(jié)構(gòu)(概念上):

    struct Student_IMPL {
        struct Person_IMPL person_OBJ_Storage; // 本質(zhì)上就是包含一個(gè)父類結(jié)構(gòu)體
        NSString *_school;
    };
    
    • 當(dāng)一個(gè) Student 對(duì)象被創(chuàng)建時(shí),它的內(nèi)存中不僅包含 _school,也包含從 Person 繼承來(lái)的 isa_name。
    • 方法調(diào)用時(shí),如果子類沒(méi)有實(shí)現(xiàn),就會(huì)沿著這個(gè)繼承鏈(通過(guò) isa 指針)去父類中查找。
  3. 多態(tài)

    • 實(shí)現(xiàn)方式:多態(tài)在 OC 中主要通過(guò) 動(dòng)態(tài)類型(Dynamic Typing)動(dòng)態(tài)綁定(Dynamic Binding) 來(lái)實(shí)現(xiàn),這依賴于強(qiáng)大的 Runtime 機(jī)制。
    • 底層原理
      • 動(dòng)態(tài)類型id 類型和 isa 指針。一個(gè)對(duì)象在運(yùn)行時(shí)才知道其真實(shí)類型。isa 指針指向?qū)ο蟮念?,運(yùn)行時(shí)可以通過(guò) isa 查詢到對(duì)象的實(shí)際類型。
      • 動(dòng)態(tài)綁定消息傳遞(Messaging) 機(jī)制。這是 OC 多態(tài)最核心的體現(xiàn)。

    示例:

    Person *p1 = [[Person alloc] init];
    Person *p2 = [[Student alloc] init]; // 多態(tài):父類指針指向子類對(duì)象
    
    [p1 sayHello]; // 調(diào)用 Person 的 sayHello 方法
    [p2 sayHello]; // 調(diào)用 Student 的 sayHello 方法(如果Student重寫了)
    

    消息傳遞的簡(jiǎn)化過(guò)程:
    當(dāng)執(zhí)行 [p2 sayHello] 時(shí),編譯器會(huì)將其轉(zhuǎn)換為一個(gè)運(yùn)行時(shí)函數(shù)調(diào)用 objc_msgSend(p2, @selector(sayHello))。

    1. objc_msgSend 會(huì)首先找到 p2 指向的對(duì)象。
    2. 通過(guò)對(duì)象的 isa 指針找到對(duì)應(yīng)的類對(duì)象 Student。
    3. Student 的方法列表(method list)中查找 sayHello 方法。
    4. 如果找到,就跳轉(zhuǎn)到該方法的實(shí)現(xiàn)(函數(shù)指針)并執(zhí)行。
    5. 如果沒(méi)找到,就通過(guò)類對(duì)象的 super_class 指針去父類 Person 的方法列表中查找,直到根類(NSObject)。
    • 這種運(yùn)行時(shí)才決定執(zhí)行哪個(gè)方法實(shí)現(xiàn)的機(jī)制,就是動(dòng)態(tài)綁定。它允許不同的對(duì)象(Person 對(duì)象和 Student 對(duì)象)對(duì)同一消息(sayHello)做出不同的響應(yīng),這就是多態(tài)。

總結(jié):Runtime 是面向?qū)ο蟮囊?/h3>
面向?qū)ο筇匦?/th> OC 實(shí)現(xiàn)方式 底層支撐
封裝 @interface / @implementation@property、訪問(wèn)控制符 C 結(jié)構(gòu)體
繼承 : 父類名 語(yǔ)法 結(jié)構(gòu)體的內(nèi)存布局(子類結(jié)構(gòu)體包含父類結(jié)構(gòu)體)
多態(tài) 動(dòng)態(tài)類型id, isa)和 動(dòng)態(tài)綁定(消息傳遞) Runtime 運(yùn)行時(shí)機(jī)制objc_msgSend、方法列表、繼承鏈)

關(guān)鍵結(jié)論:
Objective-C 的面向?qū)ο蟛皇怯删幾g器靜態(tài)決定的,而是由 Runtime 這個(gè)動(dòng)態(tài)系統(tǒng)在程序運(yùn)行時(shí)動(dòng)態(tài)創(chuàng)建的。類的結(jié)構(gòu)、方法的查找、消息的傳遞都是在運(yùn)行時(shí)發(fā)生的。這使得 OC 非常靈活,支持如 方法交換(Method Swizzling)、動(dòng)態(tài)添加方法/屬性 等高級(jí)特性,這也是它與 C++ 等語(yǔ)言在實(shí)現(xiàn)面向?qū)ο笊献罡镜膮^(qū)別。

最后編輯于
?著作權(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)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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