iOS中的結構體以及isa指針

struct 結構體名{

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

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

? ? ? ? ... ...

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

};

struct {

intage?

;inttag ;

} structTwo;

typedef可以對數據類型進行重命名,因此在定義結構體的時候可以使用它來簡化操作。

/**

*? 定義結構體

*/typedef struct {

? ? char*name;//姓名

unsignedintage;//年齡

} Student;

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

? ? //聲明結構變量Student student1 = {"jredu",21};

? ? return0;

}

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

ios-結構體和類的區別:

1、結構體只能封裝屬性,類卻不僅可以封裝屬性也可以封裝方法。如果一個封裝的數據有屬性也有行為,就只能用類了。

2、結構體變量分配在棧,而OC對象分配在堆,棧的空間相對于堆來說是比較小的,但是存儲在棧中的數據訪問效率相對于堆而言是比較高

3、堆的存儲空間比較大,存儲在堆中的數據訪問效率相對于棧而言是比較低的

4、如果定義一個結構體,這個結構體中有很多屬性,那么這個時候結構體變量在棧中會占據很多空間,這樣的話就會降低效率

5、我們使用結構體的時候最好是屬性比較少的結構體對象如果屬性較多的話就要使用類了

6、結構體賦值的話是直接賦值,對象的指針,賦值的是對象的地址。

思考: 一個OC對象在內存中是如何布局的。 NSObjcet的底層實現,點擊NSObjcet進入發現NSObject的內部實現

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

"Class isa OBJC_ISA_AVAILABILITY;

#pragma clang diagnostic pop}

@end

轉化為c語言其實就是一個結構體

struct NSObject_IMPL {

? ? Class isa;

};

那么這個結構體占多大的內存空間呢,我們發現這個結構體只有一個成員,isa指針,而指針在64位架構中占8個字節。也就是說一個NSObjec對象所占用的內存是8個字節。到這里我們已經可以基本解答第一個問題。但是我們發現NSObject對象中還有很多方法,那這些方法不占用內存空間嗎?其實類的方法等也占用內存空間,但是這些方法所占用的存儲空間并不在NSObject對象中。

為了探尋OC對象在內存中如何體現,我們來看下面一段代碼

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

上面一段代碼在內存中如何體現的呢?上述一段代碼中系統為NSObject對象分配8個字節的內存空間,用來存放一個成員isa指針。那么isa指針這個變量的地址就是結構體的地址,也就是NSObjcet對象的地址。

假設isa的地址為0x100400110,那么上述代碼分配存儲空間給NSObject對象,然后將存儲空間的地址賦值給objc指針。objc存儲的就是isa的地址。objc指向內存中NSObject對象地址,即指向內存中的結構體,也就是isa的位置。

因此此結構體占用多少存儲空間,對象就占用多少存儲空間。因此結構體占用的存儲空間為,isa指針8個字節空間+int類型_no4個字節空間+int類型_age4個字節空間共16個字節空間

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

stu -> _no = 4;

stu -> _age = 5;

那么上述代碼實際上在內存中的體現為,創建Student對象首先會分配16個字節,存儲3個東西,isa指針8個字節,4個字節的_no ,4個字節的_age

那么一個NSObject對象占用多少內存??NSObjcet實際上是只有一個名為isa的指針的結構體,因此占用一個指針變量所占用的內存空間大小,如果64bit占用8個字節,如果32bit占用4個字節。

我們發現只要是繼承自NSObject的對象,那么底層結構體內一定有一個isa指針。

面試題:OC的類信息存放在哪里。 面試題:對象的isa指針指向哪里。

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

instance對象(實例對象)

class對象(類對象)

meta-class對象(元類對象)

instance對象就是通過類alloc出來的對象,每次調用alloc都會產生新的instance對象

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

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

object1和object2都是NSObject的instace對象(實例對象),但他們是不同的兩個對象,并且分別占據著兩塊不同的內存。 instance對象在內存中存儲的信息包括

isa指針

其他成員變量



衍生問題:在上圖實例對象中根本沒有看到方法,那么實例對象的方法的代碼放在什么地方呢?那么類的方法的信息,協議的信息,屬性的信息都存放在什么地方呢?

每一個類在內存中有且只有一個class對象。可以通過打印內存地址證明

class對象在內存中存儲的信息主要包括

isa指針

superclass指針

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

類的對象方法信息(instance method),類的協議信息(protocol)


成員變量的值時存儲在實例對象中的,因為只有當我們創建實例對象的時候才為成員變賦值。但是成員變量叫什么名字,是什么類型,只需要有一份就可以了。所以存儲在class對象中。

類方法放在那里??元類對象 meta-class

每個類在內存中有且只有一個meta-class對象。?meta-class對象和class對象的內存結構是一樣的,但是用途不一樣,在內存中存儲的信息主要包括

isa指針

superclass指針

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


meta-class對象和class對象的內存結構是一樣的,所以meta-class中也有類的屬性信息,類的對象方法信息等成員變量,但是其中的值可能是空的。

對象的isa指針指向哪里

當對象調用實例方法的時候,我們上面講到,實例方法信息是存儲在class類對象中的,那么要想找到實例方法,就必須找到class類對象,那么此時isa的作用就來了。

[stu studentMethod];

instance的isa指向class,當調用對象方法時,通過instance的isa找到class,最后找到對象方法的實現進行調用。

當類對象調用類方法的時候,同上,類方法是存儲在meta-class元類對象中的。那么要找到類方法,就需要找到meta-class元類對象,而class類對象的isa指針就指向元類對象

[Student studentClassMethod];復制代碼

class的isa指向meta-class 當調用類方法時,通過class的isa找到meta-class,最后找到類方法的實現進行調用

當對象調用其父類對象方法的時候,又是怎么找到父類對象方法的呢?,此時就需要使用到class類對象superclass指針。

[stu personMethod];

[stu init];

當Student的instance對象要調用Person的對象方法時,會先通過isa找到Student的class,然后通過superclass找到Person的class,最后找到對象方法的實現進行調用,同樣如果Person發現自己沒有響應的對象方法,又會通過Person的superclass指針找到NSObject的class對象,去尋找響應的方法


當類對象調用父類的類方法時,就需要先通過isa指針找到meta-class,然后通過superclass去尋找響應的方法

[Student personClassMethod];[Student load];復制代碼

當Student的class要調用Person的類方法時,會先通過isa找到Student的meta-class,然后通過superclass找到Person的meta-class,最后找到類方法的實現進行調用

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

對isa、superclass總結

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調用對象方法的軌跡,isa找到class,方法不存在,就通過superclass找父類

class調用類方法的軌跡,isa找meta-class,方法不存在,就通過superclass找父類

本文面試題總結:

一個NSObject對象占用多少內存?

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

對象的isa指針指向哪里?

答:instance對象的isa指針指向class對象,class對象的isa指針指向meta-class對象,meta-class對象的isa指針指向基類的meta-class對象,基類自己的isa指針也指向自己。

OC的類信息存放在哪里?

答:成員變量的具體值存放在instance對象。對象方法,協議,屬性,成員變量信息存放在class對象。類方法信息存放在meta-class對象。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,606評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,582評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,540評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,028評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,801評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,223評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,294評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,442評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,976評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,800評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,996評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,543評論 5 360
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,233評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,662評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,926評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,702評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,991評論 2 374

推薦閱讀更多精彩內容