iOS中的結(jié)構(gòu)體以及isa指針

struct 結(jié)構(gòu)體名{

? ? ? ? 類型名 成員名1;

? ? ? ? 類型名 成員名2;

? ? ? ? ... ...

? ? ? ? 類型名 成員名n;

};

struct {

intage?

;inttag ;

} structTwo;

typedef可以對(duì)數(shù)據(jù)類型進(jìn)行重命名鉴竭,因此在定義結(jié)構(gòu)體的時(shí)候可以使用它來簡(jiǎn)化操作捣卤。

/**

*? 定義結(jié)構(gòu)體

*/typedef struct {

? ? char*name;//姓名

unsignedintage;//年齡

} Student;

int main(intargc,constchar* argv[]) {

? ? //聲明結(jié)構(gòu)變量Student student1 = {"jredu",21};

? ? return0;

}

//struct programmer proTest = {"Garvey",28,"13823992034"};

ios-結(jié)構(gòu)體和類的區(qū)別:

1、結(jié)構(gòu)體只能封裝屬性歧焦,類卻不僅可以封裝屬性也可以封裝方法涛菠。如果一個(gè)封裝的數(shù)據(jù)有屬性也有行為残黑,就只能用類了寝优。

2苫亦、結(jié)構(gòu)體變量分配在棧毛肋,而OC對(duì)象分配在堆,棧的空間相對(duì)于堆來說是比較小的屋剑,但是存儲(chǔ)在棧中的數(shù)據(jù)訪問效率相對(duì)于堆而言是比較高

3润匙、堆的存儲(chǔ)空間比較大,存儲(chǔ)在堆中的數(shù)據(jù)訪問效率相對(duì)于棧而言是比較低的

4唉匾、如果定義一個(gè)結(jié)構(gòu)體孕讳,這個(gè)結(jié)構(gòu)體中有很多屬性,那么這個(gè)時(shí)候結(jié)構(gòu)體變量在棧中會(huì)占據(jù)很多空間巍膘,這樣的話就會(huì)降低效率

5厂财、我們使用結(jié)構(gòu)體的時(shí)候最好是屬性比較少的結(jié)構(gòu)體對(duì)象如果屬性較多的話就要使用類了

6、結(jié)構(gòu)體賦值的話是直接賦值峡懈,對(duì)象的指針璃饱,賦值的是對(duì)象的地址。

思考: 一個(gè)OC對(duì)象在內(nèi)存中是如何布局的肪康。 NSObjcet的底層實(shí)現(xiàn)荚恶,點(diǎn)擊NSObjcet進(jìn)入發(fā)現(xiàn)NSObject的內(nèi)部實(shí)現(xiàn)

@interface NSObject {#pragma clang diagnostic push#pragma clang diagnostic ignored "-Wobjc-interface-ivars

"Class isa OBJC_ISA_AVAILABILITY;

#pragma clang diagnostic pop}

@end

轉(zhuǎn)化為c語言其實(shí)就是一個(gè)結(jié)構(gòu)體

struct NSObject_IMPL {

? ? Class isa;

};

那么這個(gè)結(jié)構(gòu)體占多大的內(nèi)存空間呢,我們發(fā)現(xiàn)這個(gè)結(jié)構(gòu)體只有一個(gè)成員磷支,isa指針谒撼,而指針在64位架構(gòu)中占8個(gè)字節(jié)。也就是說一個(gè)NSObjec對(duì)象所占用的內(nèi)存是8個(gè)字節(jié)雾狈。到這里我們已經(jīng)可以基本解答第一個(gè)問題廓潜。但是我們發(fā)現(xiàn)NSObject對(duì)象中還有很多方法,那這些方法不占用內(nèi)存空間嗎箍邮?其實(shí)類的方法等也占用內(nèi)存空間茉帅,但是這些方法所占用的存儲(chǔ)空間并不在NSObject對(duì)象中。

為了探尋OC對(duì)象在內(nèi)存中如何體現(xiàn)锭弊,我們來看下面一段代碼

NSObject *objc = [[NSObject alloc] init];

上面一段代碼在內(nèi)存中如何體現(xiàn)的呢堪澎?上述一段代碼中系統(tǒng)為NSObject對(duì)象分配8個(gè)字節(jié)的內(nèi)存空間,用來存放一個(gè)成員isa指針味滞。那么isa指針這個(gè)變量的地址就是結(jié)構(gòu)體的地址樱蛤,也就是NSObjcet對(duì)象的地址钮呀。

假設(shè)isa的地址為0x100400110,那么上述代碼分配存儲(chǔ)空間給NSObject對(duì)象昨凡,然后將存儲(chǔ)空間的地址賦值給objc指針爽醋。objc存儲(chǔ)的就是isa的地址。objc指向內(nèi)存中NSObject對(duì)象地址便脊,即指向內(nèi)存中的結(jié)構(gòu)體蚂四,也就是isa的位置。

因此此結(jié)構(gòu)體占用多少存儲(chǔ)空間哪痰,對(duì)象就占用多少存儲(chǔ)空間遂赠。因此結(jié)構(gòu)體占用的存儲(chǔ)空間為,isa指針8個(gè)字節(jié)空間+int類型_no4個(gè)字節(jié)空間+int類型_age4個(gè)字節(jié)空間共16個(gè)字節(jié)空間

Student *stu = [[Student alloc] init];

stu -> _no = 4;

stu -> _age = 5;

那么上述代碼實(shí)際上在內(nèi)存中的體現(xiàn)為晌杰,創(chuàng)建Student對(duì)象首先會(huì)分配16個(gè)字節(jié)跷睦,存儲(chǔ)3個(gè)東西,isa指針8個(gè)字節(jié)肋演,4個(gè)字節(jié)的_no ,4個(gè)字節(jié)的_age

那么一個(gè)NSObject對(duì)象占用多少內(nèi)存抑诸??NSObjcet實(shí)際上是只有一個(gè)名為isa的指針的結(jié)構(gòu)體,因此占用一個(gè)指針變量所占用的內(nèi)存空間大小爹殊,如果64bit占用8個(gè)字節(jié)蜕乡,如果32bit占用4個(gè)字節(jié)。

我們發(fā)現(xiàn)只要是繼承自NSObject的對(duì)象边灭,那么底層結(jié)構(gòu)體內(nèi)一定有一個(gè)isa指針异希。

面試題:OC的類信息存放在哪里。 面試題:對(duì)象的isa指針指向哪里绒瘦。

OC的類信息存放在哪里?OC對(duì)象主要可以分為三種

instance對(duì)象(實(shí)例對(duì)象)

class對(duì)象(類對(duì)象)

meta-class對(duì)象(元類對(duì)象)

instance對(duì)象就是通過類alloc出來的對(duì)象称簿,每次調(diào)用alloc都會(huì)產(chǎn)生新的instance對(duì)象

NSObjcet *object1 = [[NSObjcet alloc] init];

NSObjcet *object2 = [[NSObjcet alloc] init];

object1和object2都是NSObject的instace對(duì)象(實(shí)例對(duì)象),但他們是不同的兩個(gè)對(duì)象惰帽,并且分別占據(jù)著兩塊不同的內(nèi)存憨降。 instance對(duì)象在內(nèi)存中存儲(chǔ)的信息包括

isa指針

其他成員變量



衍生問題:在上圖實(shí)例對(duì)象中根本沒有看到方法,那么實(shí)例對(duì)象的方法的代碼放在什么地方呢该酗?那么類的方法的信息授药,協(xié)議的信息,屬性的信息都存放在什么地方呢呜魄?

每一個(gè)類在內(nèi)存中有且只有一個(gè)class對(duì)象悔叽。可以通過打印內(nèi)存地址證明

class對(duì)象在內(nèi)存中存儲(chǔ)的信息主要包括

isa指針

superclass指針

類的屬性信息(@property)爵嗅,類的成員變量信息(ivar)

類的對(duì)象方法信息(instance method)娇澎,類的協(xié)議信息(protocol)


成員變量的值時(shí)存儲(chǔ)在實(shí)例對(duì)象中的,因?yàn)橹挥挟?dāng)我們創(chuàng)建實(shí)例對(duì)象的時(shí)候才為成員變賦值睹晒。但是成員變量叫什么名字趟庄,是什么類型括细,只需要有一份就可以了。所以存儲(chǔ)在class對(duì)象中戚啥。

類方法放在那里奋单??元類對(duì)象 meta-class

每個(gè)類在內(nèi)存中有且只有一個(gè)meta-class對(duì)象。?meta-class對(duì)象和class對(duì)象的內(nèi)存結(jié)構(gòu)是一樣的猫十,但是用途不一樣览濒,在內(nèi)存中存儲(chǔ)的信息主要包括

isa指針

superclass指針

類的類方法的信息(class method)


meta-class對(duì)象和class對(duì)象的內(nèi)存結(jié)構(gòu)是一樣的,所以meta-class中也有類的屬性信息炫彩,類的對(duì)象方法信息等成員變量匾七,但是其中的值可能是空的絮短。

對(duì)象的isa指針指向哪里

當(dāng)對(duì)象調(diào)用實(shí)例方法的時(shí)候江兢,我們上面講到,實(shí)例方法信息是存儲(chǔ)在class類對(duì)象中的丁频,那么要想找到實(shí)例方法杉允,就必須找到class類對(duì)象,那么此時(shí)isa的作用就來了席里。

[stu studentMethod];

instance的isa指向class叔磷,當(dāng)調(diào)用對(duì)象方法時(shí),通過instance的isa找到class奖磁,最后找到對(duì)象方法的實(shí)現(xiàn)進(jìn)行調(diào)用改基。

當(dāng)類對(duì)象調(diào)用類方法的時(shí)候,同上咖为,類方法是存儲(chǔ)在meta-class元類對(duì)象中的秕狰。那么要找到類方法,就需要找到meta-class元類對(duì)象躁染,而class類對(duì)象的isa指針就指向元類對(duì)象

[Student studentClassMethod];復(fù)制代碼

class的isa指向meta-class 當(dāng)調(diào)用類方法時(shí)鸣哀,通過class的isa找到meta-class,最后找到類方法的實(shí)現(xiàn)進(jìn)行調(diào)用

當(dāng)對(duì)象調(diào)用其父類對(duì)象方法的時(shí)候吞彤,又是怎么找到父類對(duì)象方法的呢我衬?,此時(shí)就需要使用到class類對(duì)象superclass指針饰恕。

[stu personMethod];

[stu init];

當(dāng)Student的instance對(duì)象要調(diào)用Person的對(duì)象方法時(shí)挠羔,會(huì)先通過isa找到Student的class,然后通過superclass找到Person的class埋嵌,最后找到對(duì)象方法的實(shí)現(xiàn)進(jìn)行調(diào)用破加,同樣如果Person發(fā)現(xiàn)自己沒有響應(yīng)的對(duì)象方法,又會(huì)通過Person的superclass指針找到NSObject的class對(duì)象莉恼,去尋找響應(yīng)的方法


當(dāng)類對(duì)象調(diào)用父類的類方法時(shí)拌喉,就需要先通過isa指針找到meta-class速那,然后通過superclass去尋找響應(yīng)的方法

[Student personClassMethod];[Student load];復(fù)制代碼

當(dāng)Student的class要調(diào)用Person的類方法時(shí),會(huì)先通過isa找到Student的meta-class尿背,然后通過superclass找到Person的meta-class端仰,最后找到類方法的實(shí)現(xiàn)進(jìn)行調(diào)用

https://juejin.im/post/5ac81c75518825556534c0af

對(duì)isa、superclass總結(jié)

instance的isa指向class

class的isa指向meta-class

meta-class的isa指向基類的meta-class田藐,基類的isa指向自己

class的superclass指向父類的class荔烧,如果沒有父類,superclass指針為nil

meta-class的superclass指向父類的meta-class汽久,基類的meta-class的superclass指向基類的class

instance調(diào)用對(duì)象方法的軌跡鹤竭,isa找到class,方法不存在景醇,就通過superclass找父類

class調(diào)用類方法的軌跡臀稚,isa找meta-class,方法不存在三痰,就通過superclass找父類

本文面試題總結(jié):

一個(gè)NSObject對(duì)象占用多少內(nèi)存吧寺?

答:一個(gè)指針變量所占用的大小(64bit占8個(gè)字節(jié)散劫,32bit占4個(gè)字節(jié))

對(duì)象的isa指針指向哪里稚机?

答:instance對(duì)象的isa指針指向class對(duì)象,class對(duì)象的isa指針指向meta-class對(duì)象获搏,meta-class對(duì)象的isa指針指向基類的meta-class對(duì)象赖条,基類自己的isa指針也指向自己。

OC的類信息存放在哪里常熙?

答:成員變量的具體值存放在instance對(duì)象纬乍。對(duì)象方法,協(xié)議症概,屬性蕾额,成員變量信息存放在class對(duì)象。類方法信息存放在meta-class對(duì)象彼城。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末诅蝶,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子募壕,更是在濱河造成了極大的恐慌调炬,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件舱馅,死亡現(xiàn)場(chǎng)離奇詭異缰泡,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門棘钞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來缠借,“玉大人,你說我怎么就攤上這事宜猜∑梅担” “怎么了?”我有些...
    開封第一講書人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵姨拥,是天一觀的道長(zhǎng)绅喉。 經(jīng)常有香客問我,道長(zhǎng)叫乌,這世上最難降的妖魔是什么柴罐? 我笑而不...
    開封第一講書人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮憨奸,結(jié)果婚禮上革屠,老公的妹妹穿的比我還像新娘。我一直安慰自己膀藐,他們只是感情好屠阻,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著额各,像睡著了一般。 火紅的嫁衣襯著肌膚如雪吧恃。 梳的紋絲不亂的頭發(fā)上虾啦,一...
    開封第一講書人閱讀 51,737評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音痕寓,去河邊找鬼傲醉。 笑死,一個(gè)胖子當(dāng)著我的面吹牛呻率,可吹牛的內(nèi)容都是我干的硬毕。 我是一名探鬼主播,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼礼仗,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼吐咳!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起元践,我...
    開封第一講書人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤韭脊,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后单旁,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體沪羔,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年象浑,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蔫饰。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片琅豆。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖篓吁,靈堂內(nèi)的尸體忽然破棺而出趋距,到底是詐尸還是另有隱情,我是刑警寧澤越除,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布节腐,位于F島的核電站,受9級(jí)特大地震影響摘盆,放射性物質(zhì)發(fā)生泄漏翼雀。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一孩擂、第九天 我趴在偏房一處隱蔽的房頂上張望狼渊。 院中可真熱鬧,春花似錦类垦、人聲如沸狈邑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽米苹。三九已至,卻和暖如春砰琢,著一層夾襖步出監(jiān)牢的瞬間蘸嘶,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工陪汽, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留训唱,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓挚冤,卻偏偏與公主長(zhǎng)得像况增,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子训挡,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355

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