OC-終探-對象原理-【Alloc init】

[TOC]

前言

  • 本文主要圍繞以下幾點內(nèi)容展開討論;

ISA是何時和創(chuàng)建的對象進(jìn)行綁定的?(ISA最重要的目的就是關(guān)聯(lián)了對象和類)

ISA的成員(關(guān)聯(lián)類)

類在內(nèi)存里面只有一份如何證明?

類、元類、根元類分別是如何指向的?

類的本質(zhì)是什么?

對象的本質(zhì)是什么?

ISA成員

isa成員

1、根據(jù)nonpointer這個值來判斷當(dāng)前ISA指向的是純isa指針,還是bits

  • nonpointer為0: 存isa
  • nonpointer為1: 不止是類對象地址,isa包含類信息,對象的引用計數(shù)等;

2、has_assoc關(guān)聯(lián)對象標(biāo)識符,0沒有,1存在;

3、has_cxx_dtor

has_cxx_dtor

4、shiftcls

shiftcls

5、magic、weakly_referenceddeall0cating、has_sidetable_rc

image

6、extra_rc

extra_rc

ISA關(guān)聯(lián)對象與類

  • ISA綁定代碼
ISA綁定對象
  • ISA64字節(jié)成員(x86_64和__arm64是不同的);

二進(jìn)制打印

p/t打印

八進(jìn)制打印

p/o打印

十進(jìn)制打印

p/d打印

對象內(nèi)存ISA
  • 如何證明ISA指針指向的是當(dāng)前alloc的類?

方案1

對象內(nèi)存ISA

方案2
1、x/4gx打印對象的地址值;
2、取出第一位的ISA地址值;
3、獲取當(dāng)前創(chuàng)建對象的class
4、用當(dāng)前對象的地址值&ISA_MASK也就是0x00007ffffffffff8
5、最終得到該地址值和第一位的ISA獲取的地址值是一致的,這就驗證了ISA指向的就是當(dāng)前alloc的類;

  • 代碼走向;
    object_getClass-->obj->getIsa();-->ISA();-->return (Class)(isa.bits & ISA_MASK);

子網(wǎng)掩碼或者位運算的目的都是為了讓某一段內(nèi)存進(jìn)行展示

對象內(nèi)存ISA

類在內(nèi)存里面只有一份如何證明?

對象內(nèi)存ISA

思考:子類的ISA和父類的ISA是不是同一個ISA?

答案:肯定不是一個?。?br>

對象內(nèi)存ISA

元類&根元類

:代碼寫出來的-->內(nèi)存只有一份-->不是手動個創(chuàng)建的是系統(tǒng)自己創(chuàng)建的;
元類:系統(tǒng)編譯的-->發(fā)現(xiàn)了系統(tǒng)有這樣一個類-->系統(tǒng)也同時創(chuàng)建了編譯器;

對象ISA--> 圖解

對象內(nèi)存ISA
獲取類的方法
object_getClass(object)

對象ISA-->--類ISA>元類

解釋:對象是由類實例化創(chuàng)建的,那類也是由元類實例化創(chuàng)建的。

對象ISA-->-->元類 圖解

對象內(nèi)存ISA

對象ISA-->-->元類-->根元類 圖解

對象ISA-->-->元類-->根元類-->根元類 圖解

  • 第一種情況,當(dāng)創(chuàng)建的對象是NSObject時;
對象內(nèi)存ISA
  • 第二種情況,當(dāng)創(chuàng)建的對象是NSObject的子類時;
對象內(nèi)存ISA
  • 總結(jié):元類和根元類在創(chuàng)建的對象是NSObject時候可能是相同的,但是當(dāng)創(chuàng)建的對象是NSObject的子類的時候元類和根元類就不是相同的,主要是根據(jù)集成的層級管理來決定元類、根元類、根根元類的具體內(nèi)容;層級越多代表創(chuàng)建的根元類越多;

ISA走位

ISA走位原圖
ISA走位分析圖

要點
1、圖中要分為兩個維度去看(superclass繼承鏈、ISA走位鏈)
2、繼承鏈(子類-->父類-->NSObject類-->nil找方法找不到才指向nil)
3、ISA走位鏈(對象ISA-->-->元類-->根元類-->根元類)
4、根元類也繼承與NSObject

類的本質(zhì)

xoce快捷鍵:command + shift + 0 進(jìn)入xcode幫助模式;

官網(wǎng)地址:Type Encodings官網(wǎng)地址

類(NSObject)是什么時候創(chuàng)建的?

答案:NSObject這個基類在程序啟動的時候他就創(chuàng)建了, 在編譯器創(chuàng)建的。

類的本質(zhì)是什么?

答案:類的本質(zhì)就是oject_class,是一個結(jié)構(gòu)體!

objc_class內(nèi)部的結(jié)構(gòu)是什么樣子的?

類的本質(zhì)

對象的本質(zhì)

對象的本質(zhì)是什么?

答案:對象的本質(zhì)就是結(jié)構(gòu)體!

  • 驗證對象的本質(zhì)是結(jié)構(gòu)體-步驟1:

1、思考,我們寫的.m文件在xcode編譯的過程中變成了什么?
2、創(chuàng)建一個空的工程, show in finder到.m文件到目錄,打開終端;執(zhí)行命令; main.m是當(dāng)前.m文件的名稱,main3.cpp是即將生成文件的名稱;
$ clang -x objective-c -rewrite-objc main.m -o main3.cpp
3、打開main3.cpp文件;


對象的本質(zhì)

4、找到該對象名對應(yīng)的結(jié)構(gòu)體截圖;


對象的本質(zhì)

對象的本質(zhì)

疑問:默認(rèn)的成員里面的struct NSObject_IMPL 里面有什么成員?

回答:struct NSObject_IMPL 里面的成員變量是 isa(見下圖)

對象的本質(zhì)

5、結(jié)構(gòu)體中的NSObject_IVARS成員是繼承來的;其他的成員變量或者屬性是我們聲明出來的;

成員變量和屬性在編譯的過程當(dāng)中有什么區(qū)別?

答案: 成員變量沒有set、get方法,屬性有set、get的方法;

結(jié)論: 屬性 = 成員變量 + get方法 + set方法;

對象的本質(zhì)

備注:如果在使用終端clang命令報錯,報錯內(nèi)容是"缺少UIKit庫的問題,請執(zhí)行下面指令到控制臺即可"

對象的本質(zhì)

總結(jié)

ISA是何時和創(chuàng)建的對象進(jìn)行綁定的?

答案:ISA最重要的目的就是關(guān)聯(lián)了對象和類 isa <-> cls;

如何獲取一個類的父類?

  • 步驟1

object_getClass方法即可;

Class object_getClass(id obj)
{
    if (obj) return obj->getIsa();
    else return Nil;
}
  • 步驟2

getIsa方法即可;

objc_object::getIsa() 
{
    if (!isTaggedPointer()) return ISA();

    uintptr_t ptr = (uintptr_t)this;
    if (isExtTaggedPointer()) {
        uintptr_t slot = 
            (ptr >> _OBJC_TAG_EXT_SLOT_SHIFT) & _OBJC_TAG_EXT_SLOT_MASK;
        return objc_tag_ext_classes[slot];
    } else {
        uintptr_t slot = 
            (ptr >> _OBJC_TAG_SLOT_SHIFT) & _OBJC_TAG_SLOT_MASK;
        return objc_tag_classes[slot];
    }
}
  • 步驟3

ISA()方法即可;

objc_object::ISA() 
{
    assert(!isTaggedPointer()); 
#if SUPPORT_INDEXED_ISA
    if (isa.nonpointer) {
        uintptr_t slot = isa.indexcls;
        return classForIndex((unsigned)slot);
    }
    return (Class)isa.bits;
#else
    return (Class)(isa.bits & ISA_MASK);
#endif
}
  • 關(guān)鍵代碼
    return (Class)(isa.bits & ISA_MASK);

isa.bits就是當(dāng)前isa指向的地址值,ISA_MASK就是掩碼,這個位置可以看本文ISA關(guān)聯(lián)對象與類的節(jié)點;

ISA指向

對象ISA-->-->元類-->根元類-->根元類

class的繼承管理

子類subclass-->父類superclass-->NSObject-->nil

根元類父類NSObject

類的本質(zhì)是什么?

結(jié)構(gòu)體;

對象的本質(zhì)是什么?

結(jié)構(gòu)體;

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

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