OC類與對象的內(nèi)存模型以及方法和成員變量的訪問原理

1.整理的對象和類的c實現(xiàn):


這是大概結(jié)構(gòu)桑驱,具體要比這個復(fù)雜一些泞遗,具體看文件(準(zhǔn)備匆忙隨后貼上源碼):


2.查看Dad類和Child類用clang生成的c代碼:

先解釋一下類結(jié)構(gòu)? 有 Dad(父類) 和 Child(子類) 兩個類, Dad類有 dadName 屬性和 _dadIvarName 成員變量;

Child 類有 childName 屬性和 _childIvarName 成員變量; 兩個類都含有 -(void)testAddress; 和 -(void)printIvars;方法谱轨;(準(zhǔn)備匆忙劈榨,隨后貼上類結(jié)構(gòu)圖)

先是Dad對象用clang生成的c代碼(clang命令在下面):

? ? ? ? ? ? ? ? ? ? ??

然后是Child對象:

??

可以看到即使是繼承關(guān)系中,每個類都有且只有自己的成員變量粒梦,屬性和方法列表亮航;子類中并不包含父類的成員變量,屬性和方法等匀们;


3.查看通過屬性訪問和下劃線成員變量訪問的c代碼:

包括:通過clang生成的c代碼,其中包括:1.通過setter方法訪問父類和子類屬性; 2.通過下劃線_屬性名訪問的父類和子類實例變量;

? ? ? ? ? ? ? ? ? ?- (void)testAddress {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?self.dadName = @"1";

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? _dadIvarName = @"2";

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? self.childName = @"3";

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? _childIvarName = @"4";

? ? ? ? ? ? ? ? ? ? }

命令: ? ? ? clang -rewrite-objc Child.m

??

? ? ? ?1.可以看到通過setter方法訪問的父類和子類的屬性都是通過消息機(jī)制發(fā)送給self缴淋,但是根據(jù)OC的消息機(jī)制可以知道,如果是父類的方法會通過superclass找到父類,去父類方法列表找到這個方法;這個setter方法是在父類的.m里邊生成的,然后通過給_dadname賦值昼蛀;

? ? ? ? 2.如果是通過下劃線+成員變量名訪問的話宴猾,可以看到如果是父類的成員變量,根據(jù)_dadIvarName生成的代碼中含有的的類名Dad叼旋,以及_childIvarName中含有的類名Child可以知道,其實編譯完成就已經(jīng)知道屬性是屬于哪個類仇哆;

? ? ? ?3.我們可以看到通過成員變量訪問時的c代碼:

? ? ? ?等號的左邊是(self + OBJC_IVAR_$_Dad$_dadIvarName) ? 翻譯一下這不就是:

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?成員變量地址 = (對象地址 + 屬于Dad類的_dadIvarName屬性)

? ? ? 或者可以理解為: ? ? ? ? ? ? ?_dadIvarName地址 = 當(dāng)前對象地址 + Dad類中_dadIvarName屬性的偏移量

關(guān)于尋找成員變量的偏移量,貼上王曉磊《Objective-C類成員變量深度剖析》中的一段代碼:

?

可以看到其實編譯生成的test.ll文件中的LLVM IR代碼里顯示夫植,其實尋找成員變量偏移量是利用分配成全局變量在編譯期間就已經(jīng)確定讹剔,不需要在運(yùn)行時執(zhí)行繁瑣的尋找過程;

4.查看對象中成員變量的內(nèi)存(包括從父類繼承來的以及當(dāng)前類自身的),下圖是打印父類(上)和子類(下)成員變量的代碼:

? ? ? ? ? ? ? ? ? ?
? ? ??

下圖是輸出的結(jié)果:

根據(jù)上圖可以看到父類和子類成員變量名以及偏移量详民,偏移量是從父類第一變量開始到子類最后一個成員變量順序排布依次增大, 便宜量都依次加8是因為64位下指針是8個字節(jié)(我們的 _dadName 等都是字符串), 第一個成員變量便宜量是8是因為對象第一個內(nèi)容是一個為8個字節(jié)的指向類的isa指針;

下面看看對象的首地址以及對象中各成員變量的地址:

? ? ? ?以下是打印地址的代碼:(子類調(diào)父類同名方法)

父類打印地址代碼(被子類調(diào)用)
? ? ? ??
子類打印地址代碼(先調(diào)用父類的打印方法)

以及輸出的結(jié)果:

?

可以看到延欠,打印的16進(jìn)制地址從父類到子類根據(jù)偏移量依次增長,且符合: ?

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?成員變量地址 = 對象(首)地址 + 該成員變量的偏移量;

所以可以得出對象在堆中的地址如右圖所示分配:

可以復(fù)習(xí)一下結(jié)構(gòu)體的性質(zhì)沈跨,結(jié)構(gòu)體是按照其中size最大的變量的size來分配內(nèi)存(即為一個變量分配一塊新空間時最小增加量是size)由捎,當(dāng)前一個指針是8個字節(jié),所以便宜量差值都是8饿凛。

5.xcode屬性的自動合成機(jī)制生成的成員變量是私有的(基于蘋果的設(shè)計理念狞玛,以及atomic關(guān)鍵字,KVO等對直接訪問成員變量的方式是不生效的(需要通過setter 软驰,getter方法),關(guān)于Non Fragile ivars 機(jī)制:(隨后補(bǔ)上)

6.不能動態(tài)增加成員變量,以及分類的關(guān)聯(lián)對象:(隨后補(bǔ)上)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末心肪,一起剝皮案震驚了整個濱河市锭亏,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌硬鞍,老刑警劉巖慧瘤,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異固该,居然都是意外死亡锅减,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進(jìn)店門蹬音,熙熙樓的掌柜王于貴愁眉苦臉地迎上來上煤,“玉大人,你說我怎么就攤上這事著淆〗俸荩” “怎么了?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵永部,是天一觀的道長独泞。 經(jīng)常有香客問我,道長苔埋,這世上最難降的妖魔是什么懦砂? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮组橄,結(jié)果婚禮上荞膘,老公的妹妹穿的比我還像新娘。我一直安慰自己玉工,他們只是感情好羽资,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著遵班,像睡著了一般屠升。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上狭郑,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天腹暖,我揣著相機(jī)與錄音,去河邊找鬼翰萨。 笑死脏答,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播以蕴,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼糙麦,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了丛肮?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤魄缚,失蹤者是張志新(化名)和其女友劉穎宝与,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體冶匹,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡习劫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了嚼隘。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片诽里。...
    茶點(diǎn)故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖飞蛹,靈堂內(nèi)的尸體忽然破棺而出谤狡,到底是詐尸還是另有隱情,我是刑警寧澤卧檐,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布墓懂,位于F島的核電站,受9級特大地震影響霉囚,放射性物質(zhì)發(fā)生泄漏捕仔。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一盈罐、第九天 我趴在偏房一處隱蔽的房頂上張望榜跌。 院中可真熱鬧,春花似錦盅粪、人聲如沸钓葫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽瓤逼。三九已至,卻和暖如春库物,著一層夾襖步出監(jiān)牢的瞬間霸旗,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工戚揭, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留诱告,地道東北人。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓民晒,卻偏偏與公主長得像精居,于是被迫代替她去往敵國和親锄禽。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評論 2 354

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