OC對象的本質(zhì)

總結(jié)性文章凤薛,如有問題丢习,請評論

image.png

從以下幾個維度分析

1.對象的分類
  • 首先按分類來說辛萍,OC對象分為實例對象想暗、類對象诫给、元類對象三種毒姨。
    他們的底層實現(xiàn)都是結(jié)構(gòu)體.
2.內(nèi)部實現(xiàn)
  • 實例對象
@interface NSObject <NSObject> {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-interface-ivars"
    Class isa  OBJC_ISA_AVAILABILITY;
#pragma clang diagnostic pop
}

Class的內(nèi)部實現(xiàn)
typedef struct objc_class *Class; 

所以ISA是一個指向結(jié)構(gòu)體的指針變量

當(dāng)繼承發(fā)生時

struct NSobject_imp{
        Class imp;
    };
    
    struct Person {
        struct NSobject_imp imp_isa;
        int _age;
        int _num;
        int _on;
    };
通俗理解,生成的person實例對象中衣陶,包含三個ivar + NSObject的ISA指針

實例對象的結(jié)構(gòu)如下:

  • ISA //指向父類的指針
  • _ivar //成員變量
  • _ivar //成員變量
  • _ivar //成員變量

類對象class
通過xcode查看的類對象已經(jīng)過時,下邊是之前的定義财饥,最新的定義可以查看objc的源碼墩衙,在下邊列出幾個重要的點

struct objc_class {
    Class _Nonnull isa  OBJC_ISA_AVAILABILITY;

#if !__OBJC2__
    Class _Nullable super_class                              OBJC2_UNAVAILABLE;
    const char * _Nonnull name                               OBJC2_UNAVAILABLE;
    long version                                             OBJC2_UNAVAILABLE;
    long info                                                OBJC2_UNAVAILABLE;
    long instance_size                                       OBJC2_UNAVAILABLE;
    struct objc_ivar_list * _Nullable ivars                  OBJC2_UNAVAILABLE;
    struct objc_method_list * _Nullable * _Nullable methodLists                    OBJC2_UNAVAILABLE;
    struct objc_cache * _Nonnull cache                       OBJC2_UNAVAILABLE;
    struct objc_protocol_list * _Nullable protocols          OBJC2_UNAVAILABLE;
#endif

} OBJC2_UNAVAILABLE;

新版

struct objc_class : objc_object {
    // Class ISA;
    Class superclass;
    cache_t cache;             // formerly cache pointer and vtable
    class_data_bits_t bits;    // class_rw_t * plus custom rr/alloc flags
最新版的ISA被注釋掉了躺孝,不要被迷惑享扔,只要是對象,就會有ISA植袍,實際是objc_class繼承于objc_object
而...
struct objc_object {
    Class _Nonnull isa  OBJC_ISA_AVAILABILITY;
};

然后展開class_data_bits_t里邊public的 class_rw_t, 看通過 rw可以了解惧眠,這部分是可以讀寫的 

struct class_rw_t {
    // Be warned that Symbolication knows the layout of this structure.
    uint32_t flags;
    uint16_t version;
    uint16_t witness;
    const class_ro_t *ro;   //不可寫部分
    method_array_t methods; //方法列表
    property_array_t properties;// 屬性列表
    protocol_array_t protocols; //協(xié)議列表
    Class firstSubclass; 
    Class nextSiblingClass;
    char *demangledName;
}

這是 class_ro_t  可讀不可寫的部分 
struct class_ro_t {
    uint32_t flags;
    uint32_t instanceStart;
    uint32_t instanceSize;   //實例的大小
#ifdef __LP64__
    uint32_t reserved;
#endif
  t uint8_t * ivarLayout;
    
    const char * name;  //類名
    method_list_t * baseMethodList; //最初的方法列表
    protocol_list_t * baseProtocols; //最初的協(xié)議列表
    const ivar_list_t * ivars; //成員變量列表
    const uint8_t * weakIvarLayout;
    property_list_t *baseProperties;
}

通過上述幾個機(jī)構(gòu)提可以看出,類對象的基本結(jié)構(gòu)如下

  • ISA // 指向元類指針
  • superclass //指向父類的指針
  • cache //方法緩存列表于个,注意是對象方法
  • bits //里邊有基本的可變的一堆屬性和不可變的一堆屬性

針對bits里邊可變不可變的屬性做個補(bǔ)充:

  1. method 和 protocol 這些通過運行時可以動態(tài)添加氛魁;properties可以在分類中添加(只不過值是存儲在一個全局的散列表中的)
  2. ivars這個是不可變的,也就是說厅篓,不能向一個已經(jīng)創(chuàng)建好的類中添加ivar秀存,這是因為,在實例化實例對象的時候羽氮,內(nèi)存大小是固定的或链。(instanceSize)
    實例結(jié)構(gòu)體中包含的就是ISA指針和ivars的列表。

元類對象
元類對象是類對象的一種档押,內(nèi)部結(jié)構(gòu)和類對象一樣澳盐,在創(chuàng)建類對象的時候,會同時創(chuàng)建一個元類對象出來令宿。
只不過內(nèi)部存儲的值和類對象是不一樣的叼耙,元類對象中存儲的是類方法

  • ISA // 指向基類元類指針(注:此處的ISA指針直接指向NSObject的元類)
  • superclass //指向父類的元類的指針
  • cache //方法緩存列表粒没,注意類象方法
  • bits //類方法

總結(jié):起始根據(jù)這三種對象筛婉,體現(xiàn)了程序的分層設(shè)計的原則,最上層包含的是成員變量癞松、下一層包含各種方法和緩存爽撒、再進(jìn)一層就是只有類才能調(diào)用的類方法。

3.占用空間的大小

我們創(chuàng)建一個實例對象响蓉,占用的內(nèi)存空間的大小是怎么樣的硕勿,找到最上邊實例的結(jié)構(gòu)體樣式。

  • ISA //指向父類的指針
  • _ivar //成員變量
  • _ivar //成員變量
  • _ivar //成員變量
    我們可以看到厕妖,包含一個ISA指針首尼,還有不等的ivar,占用的大小可以直接算出言秸,指針變量8個字節(jié)软能,int 類型 4個字節(jié)... 相加就得出了。
    但是注意:結(jié)構(gòu)體在創(chuàng)建的時候举畸,有內(nèi)存對齊的概念查排,必須是8的整數(shù)倍,也就是當(dāng)內(nèi)存占用20個字節(jié)抄沮,會給你分配24個字節(jié)跋核。
    C函數(shù)還有一層內(nèi)存對齊的概念岖瑰,他分配內(nèi)存大小是16的整數(shù)倍
4.方法調(diào)用

直接拿網(wǎng)上的圖


查找流程.png

先看ISA 和 superclass這兩個指針的指向
ISA - > 父類
父類ISA - >元類
元類ISA - > Root Meta Class

Subclass 的superclass指針 - > Superclass
Superclass 的 superclass指針 - > NSObject

對象方法:根據(jù)ISA指針找到自己的父類-- >查找父類cache緩存 -->查找父類methodlist --> 根據(jù)superclass指針 -- > Superclass的cache --- > Superclass的methodlist ---> NSObject...

類方法:根據(jù)ISA指針找到Metaclass的cache -- > Metaclass 的methodlist -- > 根據(jù)superclass指針周到 Superclass Meta的cache ....

其他補(bǔ)充

1.關(guān)于ISA指針中存儲的地址不是類對象首地址的原因
由于在新版ISA指針做了優(yōu)化,8個字節(jié) 64位的存儲空間砂代,不僅存儲指向類對象的地址蹋订,還保存了一些標(biāo)志位信息,包括是否有關(guān)聯(lián)對象刻伊、是否有弱引用露戒、引用計數(shù)存儲等。所以要取出這個地址還是要 & 上下邊的地址捶箱。


ISA_MASK2020-02-29上午8.31.58.png

2.類方法在尋找的時候智什,找到NSObject的元類中,如果還是沒有丁屎,還會去NSObject類中尋找是否有相同符號的對象方法荠锭。
3.獲取元類的方式object_getClass([NSObject class]);傳遞一個類對象進(jìn)去,就可以獲取晨川。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末证九,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子础爬,更是在濱河造成了極大的恐慌甫贯,老刑警劉巖吼鳞,帶你破解...
    沈念sama閱讀 212,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件看蚜,死亡現(xiàn)場離奇詭異,居然都是意外死亡赔桌,警方通過查閱死者的電腦和手機(jī)供炎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來疾党,“玉大人音诫,你說我怎么就攤上這事⊙┪唬” “怎么了竭钝?”我有些...
    開封第一講書人閱讀 158,369評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長雹洗。 經(jīng)常有香客問我香罐,道長,這世上最難降的妖魔是什么时肿? 我笑而不...
    開封第一講書人閱讀 56,799評論 1 285
  • 正文 為了忘掉前任庇茫,我火速辦了婚禮,結(jié)果婚禮上螃成,老公的妹妹穿的比我還像新娘旦签。我一直安慰自己查坪,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,910評論 6 386
  • 文/花漫 我一把揭開白布宁炫。 她就那樣靜靜地躺著偿曙,像睡著了一般。 火紅的嫁衣襯著肌膚如雪羔巢。 梳的紋絲不亂的頭發(fā)上遥昧,一...
    開封第一講書人閱讀 50,096評論 1 291
  • 那天,我揣著相機(jī)與錄音朵纷,去河邊找鬼炭臭。 笑死,一個胖子當(dāng)著我的面吹牛袍辞,可吹牛的內(nèi)容都是我干的鞋仍。 我是一名探鬼主播,決...
    沈念sama閱讀 39,159評論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼搅吁,長吁一口氣:“原來是場噩夢啊……” “哼威创!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起谎懦,我...
    開封第一講書人閱讀 37,917評論 0 268
  • 序言:老撾萬榮一對情侶失蹤肚豺,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后界拦,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體吸申,經(jīng)...
    沈念sama閱讀 44,360評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,673評論 2 327
  • 正文 我和宋清朗相戀三年享甸,在試婚紗的時候發(fā)現(xiàn)自己被綠了截碴。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,814評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡蛉威,死狀恐怖日丹,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蚯嫌,我是刑警寧澤哲虾,帶...
    沈念sama閱讀 34,509評論 4 334
  • 正文 年R本政府宣布,位于F島的核電站择示,受9級特大地震影響束凑,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜对妄,卻給世界環(huán)境...
    茶點故事閱讀 40,156評論 3 317
  • 文/蒙蒙 一湘今、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧剪菱,春花似錦摩瞎、人聲如沸拴签。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蚓哩。三九已至,卻和暖如春上渴,著一層夾襖步出監(jiān)牢的瞬間岸梨,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評論 1 267
  • 我被黑心中介騙來泰國打工稠氮, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留曹阔,地道東北人。 一個月前我還...
    沈念sama閱讀 46,641評論 2 362
  • 正文 我出身青樓隔披,卻偏偏與公主長得像赃份,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子奢米,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,728評論 2 351