筆記 - OC對(duì)象的本質(zhì)

我們平時(shí)編寫的Object-C代碼蛇尚,底層實(shí)現(xiàn)其實(shí)都是C/C++代碼,基于C/C++結(jié)構(gòu)體實(shí)現(xiàn)的

目錄

  • 1、OC對(duì)象的本質(zhì)
    • 1.1. 面試題
    • 1.2. Go2Shell插件(快速定位終端)
    • 1.3. 使用clang將OC代碼轉(zhuǎn)為C/C++
    • 1.4. 實(shí)時(shí)查看內(nèi)存數(shù)據(jù)
    • 1.5. 復(fù)雜的繼承結(jié)構(gòu)分析
    • 1.6. 屬性和方法

1.1、面試題

  • 一個(gè)NSObject對(duì)象占用多少內(nèi)存锦担?
// 獲得NSObject類的實(shí)例對(duì)象的成員變量所占用的大小 >> 8
NSLog(@"%zd", class_getInstanceSize([NSObject class]));
// 獲得obj指針?biāo)赶騼?nèi)存大小 >>16
NSLog(@"%zd", malloc_size((__bridge const void *)obj));

2019-06-01 16:16:19.774722+0800 Interview001-OC對(duì)象的本質(zhì)[2222:353779] 8
2019-06-01 16:16:19.774927+0800 Interview001-OC對(duì)象的本質(zhì)[2222:353779] 16

結(jié)論:
- 系統(tǒng)分配了16個(gè)字節(jié)給 NSObject 對(duì)象
- 但 NSObject 對(duì)象內(nèi)部只使用了8個(gè)字節(jié)的空間诬滩,存放的是isa指針
  • 對(duì)象的isa指針指向哪里?
- instance對(duì)象的isa指向class對(duì)象
- class對(duì)象的isa指向meta-class對(duì)象
- meta-class對(duì)象的isa指基類的meta-class對(duì)象
  • OC的類信息存放在哪里坊饶?
- 對(duì)象方法、屬性殴蓬、成員變量匿级、協(xié)議信息,存放在class對(duì)象中
- 類方法染厅,存放在meta-class對(duì)象中
- 成員變量的具體值痘绎,存放在instance對(duì)象中

1.2、Go2Shell插件 官網(wǎng)

下載
安裝
使用

1.3肖粮、clang將OC代碼轉(zhuǎn)為C/C++

?? 首先定位到當(dāng)前文件夾下

$ clang -rewrite-objc main.m -o main.cpp

// 指定平臺(tái)和架構(gòu)
$ xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc [輸入文件] -o [輸入文件]
// 在Xcode下可使用以下命令:
$ xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o main-arm64.cpp
$ xcrun -sdk iphoneos clang -arch i386 -rewrite-objc main.m -o main-i386.cpp

可參考:使用clang將OC代碼轉(zhuǎn)為C/C++ - Cotin's

轉(zhuǎn)換結(jié)果

通過將OC轉(zhuǎn)換為C/C++代碼孤页,我們從源碼中可查看NSObject的底層實(shí)現(xiàn)

@interface NSObject {
    Class isa;
}
@end

=>

struct NSObject_IMPL {
    Class isa;
};

// Class 是指向結(jié)構(gòu)體的指針
typedef struct objc_class *Class;

創(chuàng)建一個(gè)Student類

struct NSObject_IMPL {
    Class isa;
};

struct Student_IMPL {
    struct NSObject_IMPL NSObject_IVARS;
    int _no;
    int _age;
};

@interface Student : NSObject
{
    @public
    int _no;
    int _age;
}
@end

@implementation Student

@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Student *student = [[Student alloc] init];
        student->_no = 4;
        student->_age = 5;
        
        struct Student_IMPL *stuImpl = (__bridge struct Student_IMPL *)(student);
        NSLog(@"no is %d, age is %d", stuImpl->_no, stuImpl->_age);
    }
    return 0;
}

2019-06-01 21:04:08.746698+0800 Interview002[2973:555547] no is 4, age is 5
20_58_22__06_01_2019.jpg

1.4、實(shí)時(shí)查看內(nèi)存數(shù)據(jù)

Debug -> Debug Workflow -> View Memory (Shift + Command + M)


1dm9tuPP22_47_07__06_02_2019.jpg

1eY6ToWS22_47_51__06_02_2019.jpg

1.5尿赚、復(fù)雜的繼承結(jié)構(gòu)分析

一個(gè)Student對(duì)象繼承于Person對(duì)象散庶,Student占用多少內(nèi)存空間蕉堰?

@interface Person : NSObject
{
    int _age;
}
@end

@interface Student : Person
{
    int _no;
}
@end

分析結(jié)果

struct NSObject_IMPL {
    Class isa;
};

struct Person_IMPL {
    struct NSObject_IMPL NSObject_IVARS;
    int _age;
};

struct Student_IMPL {
    struct Person_IMPL Person_IVARS;
    int _no;
};

1.6、屬性和方法

@interface Person : NSObject
{
    int _age;
}
@property(nonatomic, assign) int height;

@end

=>

struct Person_IMPL {
    struct NSObject_IMPL NSObject_IVARS;
    int _age;
    int _height;
};

我們創(chuàng)建出來的實(shí)例對(duì)象悲龟,內(nèi)存中只存成員變量屋讶,不存方法,為什么不設(shè)計(jì)成把方法放到實(shí)例變量里面去须教?
Person對(duì)象可能創(chuàng)建很多個(gè)皿渗,每一個(gè)實(shí)例對(duì)象的內(nèi)存都放自己的成員變量,方法的代碼都是一樣的轻腺,只放一份就行了乐疆。


總結(jié):知識(shí)儲(chǔ)備多,解決問題可以從多個(gè)面切入

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末贬养,一起剝皮案震驚了整個(gè)濱河市挤土,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌误算,老刑警劉巖仰美,帶你破解...
    沈念sama閱讀 218,386評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件我注,死亡現(xiàn)場(chǎng)離奇詭異齿诞,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)铭腕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門蚊夫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來诉字,“玉大人,你說我怎么就攤上這事知纷∪榔裕” “怎么了?”我有些...
    開封第一講書人閱讀 164,704評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵屈扎,是天一觀的道長(zhǎng)埃唯。 經(jīng)常有香客問我撩匕,道長(zhǎng)鹰晨,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,702評(píng)論 1 294
  • 正文 為了忘掉前任止毕,我火速辦了婚禮模蜡,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘扁凛。我一直安慰自己忍疾,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,716評(píng)論 6 392
  • 文/花漫 我一把揭開白布谨朝。 她就那樣靜靜地躺著卤妒,像睡著了一般甥绿。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上则披,一...
    開封第一講書人閱讀 51,573評(píng)論 1 305
  • 那天共缕,我揣著相機(jī)與錄音,去河邊找鬼士复。 笑死图谷,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的阱洪。 我是一名探鬼主播便贵,決...
    沈念sama閱讀 40,314評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼冗荸!你這毒婦竟也來了承璃?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,230評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤蚌本,失蹤者是張志新(化名)和其女友劉穎绸硕,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體魂毁,經(jīng)...
    沈念sama閱讀 45,680評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡玻佩,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,873評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了席楚。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片咬崔。...
    茶點(diǎn)故事閱讀 39,991評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖烦秩,靈堂內(nèi)的尸體忽然破棺而出垮斯,到底是詐尸還是另有隱情,我是刑警寧澤只祠,帶...
    沈念sama閱讀 35,706評(píng)論 5 346
  • 正文 年R本政府宣布兜蠕,位于F島的核電站,受9級(jí)特大地震影響抛寝,放射性物質(zhì)發(fā)生泄漏熊杨。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,329評(píng)論 3 330
  • 文/蒙蒙 一盗舰、第九天 我趴在偏房一處隱蔽的房頂上張望晶府。 院中可真熱鬧,春花似錦钻趋、人聲如沸川陆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽较沪。三九已至鳞绕,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間尸曼,已是汗流浹背猾昆。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留骡苞,地道東北人垂蜗。 一個(gè)月前我還...
    沈念sama閱讀 48,158評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像解幽,于是被迫代替她去往敵國(guó)和親贴见。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,941評(píng)論 2 355

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