OC中對象的本質(zhì)

對象在C++層面的表現(xiàn)

我們先準備以下代碼

@interface ELPerson : NSObject



@property (nonatomic, strong) NSString *ELname;



- (void)testfunction;



@end

用如下代碼把他編譯成c++代碼

 xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o main-arm64.cpp

打開生成的.cpp文件烈钞,我們搜索一下蛙婴,找到

struct ELPerson_IMPL {

    struct NSObject_IMPL NSObject_IVARS;

    NSString *_ELname;

};

我們繼續(xù)搜索ELPerson_IMPL

struct NSObject_IMPL {

    Class isa;

};

他在c++層面就是這樣一個結(jié)構(gòu)體油坝,里面并沒有存儲我們定義的方法盒让。就是結(jié)構(gòu)體指針isa搜锰。

NSObjectruntime中對應(yīng)的源碼為

/// Represents an instance of a class.

struct objc_object {

  Class _Nonnull isa OBJC_ISA_AVAILABILITY;

};

類對象的源碼應(yīng)該為

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

汗贫。身坐。秸脱。函數(shù)

}

objc_class繼承objc_object,也就繼承了isa部蛇。這里也說明:對象包含類對象和實例對象摊唇。

探尋ISA的實現(xiàn)

我們繼續(xù)探究ISA,他的源碼應(yīng)該為如下:(x86_64架構(gòu)精簡代碼說明)

union isa_t {

涯鲁。巷查。。//省略

  struct {
   uintptr_t nonpointer    : 1;                     \

   uintptr_t has_assoc     : 1;                     \

   uintptr_t has_cxx_dtor   : 1;                     \

   uintptr_t shiftcls     : 44; /*MACH_VM_MAX_ADDRESS 0x7fffffe00000*/ \

   uintptr_t magic       : 6;                     \

   uintptr_t weakly_referenced : 1;                     \

   uintptr_t unused      : 1;                     \

   uintptr_t has_sidetable_rc : 1;                     \

   uintptr_t extra_rc     : 8

  }

};

nonpointer在0位抹腿,表示是否對isa指針開啟指針優(yōu)化岛请。0:純isa指針,這里面直接存儲Class警绩、Meta-Class 對象的地址(沒有使用位域)1:代表優(yōu)化過的崇败,使用了位域,里面包含位域里面的這些信息(類對象地址肩祥,isa包含了類信息后室、對象的引用計數(shù)等),想要得到類對象搭幻、元類對象咧擂,需要&上ISA_MASK(也可以使用地址平移)才能得到逞盆。

has_assoc在1位檀蹋,表示關(guān)聯(lián)對象標志位,0:沒有云芦,1:有俯逾。

has_cxx_dtor在2位,表示該對象是否有C++或者Objc的析構(gòu)器舅逸,如果有析構(gòu)函數(shù)桌肴,則需要做析構(gòu)邏輯,如果沒有琉历,則可以更快的釋放對象坠七。

shiftclsx86架構(gòu)中占用3~46位,表示存儲類指針的值旗笔。開啟指針優(yōu)化的情況下彪置,在arm64架構(gòu)中占用3~35位。

magicx86架構(gòu)中占用47~52位蝇恶,在arm64架構(gòu)中占用36~41位拳魁,用于調(diào)式器判斷當前對象是真的對象還是沒有初始化的空間。

weakly_referencedx86架構(gòu)中占用第53位撮弧,在arm64架構(gòu)中占用第42位潘懊,標志對象是否被指向或者曾經(jīng)指向一個ARC的弱變量姚糊,沒有弱引用的對象可以更快釋放。

unusedx86架構(gòu)中占用第54位授舟,在arm64架構(gòu)中占用第43位救恨,標志對象是否正在釋放內(nèi)存。

has_sidetable_rcx86架構(gòu)中占用第55位释树,在arm64架構(gòu)中占用第44位忿薇,表示當對象引用計數(shù)大于10時,則需要借用該變量存儲進位躏哩。

extra_rcx86架構(gòu)中占用56~63位署浩,在arm64架構(gòu)中占用45~63位,當表示該對象的引用計數(shù)值時扫尺,實際上是引用計數(shù)值減1筋栋,例如:如果對象的引用計數(shù)為10,那么extra_rc9正驻,如果引用計數(shù)大于10弊攘,則需要使用到has_sidetable_rc

我們直接測試一下shiftcls位置是否是類的信息

(lldb)x/4gx per //打印對象地址姑曙,首地址為isa

0x10065c0d0: 0x011d8001000082e5 0x0000000000000000

0x10065c0e0: 0x0000000000000000 0x0000000000000000

(lldb) p/x per.class //打印類對象地址

(Class) $8 = 0x00000001000082e0 ELPerson

(lldb)p/x 0x011d8001000082e5 >> 3 << 20 >> 17 //算法在下面說明

(long) $9 = 0x00000001000082e0 //說明對象的isa里面包含類對象的地址信息

(lldb) 

位運算圖解:

image

再打印一下二進制的內(nèi)存情況襟交,方便對照,如下:

(lldb) x/1gt per0x10065c0d0: 0b0000000100011101100000000000000100000000000000001000001011100101(lldb)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末伤靠,一起剝皮案震驚了整個濱河市捣域,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌宴合,老刑警劉巖焕梅,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異卦洽,居然都是意外死亡贞言,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進店門阀蒂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來该窗,“玉大人,你說我怎么就攤上這事蚤霞⌒锸В” “怎么了?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵争便,是天一觀的道長刊咳。 經(jīng)常有香客問我扔涧,道長廷雅,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任鉴嗤,我火速辦了婚禮,結(jié)果婚禮上序调,老公的妹妹穿的比我還像新娘醉锅。我一直安慰自己,他們只是感情好发绢,可當我...
    茶點故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布硬耍。 她就那樣靜靜地躺著,像睡著了一般边酒。 火紅的嫁衣襯著肌膚如雪经柴。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天墩朦,我揣著相機與錄音坯认,去河邊找鬼。 笑死氓涣,一個胖子當著我的面吹牛牛哺,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播劳吠,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼引润,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了痒玩?” 一聲冷哼從身側(cè)響起淳附,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎凰荚,沒想到半個月后燃观,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體褒脯,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡便瑟,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了番川。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片到涂。...
    茶點故事閱讀 39,926評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖颁督,靈堂內(nèi)的尸體忽然破棺而出践啄,到底是詐尸還是另有隱情,我是刑警寧澤沉御,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布屿讽,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏伐谈。R本人自食惡果不足惜烂完,卻給世界環(huán)境...
    茶點故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望诵棵。 院中可真熱鬧抠蚣,春花似錦、人聲如沸履澳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽距贷。三九已至柄冲,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間忠蝗,已是汗流浹背羊初。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留什湘,地道東北人长赞。 一個月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像闽撤,于是被迫代替她去往敵國和親得哆。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,871評論 2 354

推薦閱讀更多精彩內(nèi)容