iOS底層原理總結 OC物件的本質 一

2021-09-11 21:49:16 字數 3361 閱讀 9672

窺探ios底層實現--oc物件的本質(一) - 掘金

窺探ios底層實現--oc物件的本質(二) - 掘金

窺探ios底層實現--oc物件的分類:instance、class、meta-calss物件的isa和superclass - 掘金

窺探ios底層實現-- kvo/kvc的本質 - 掘金

int main(int argc, char * ar**) 

}return

0;複製**

平時我們編寫的objective-c的**,底層的實現其實都是c/c++的**。

所以objective-c 的物件導向都是基於c/c++的資料結構實現的。

思考問題: objective-c的物件、類主要是基於c\c++的什麼資料結構實現的?

///> student類

@inte***ce

student: nsobject

@end

@implementation

student

@end

int main(int argc, char * ar**)

}return

0;複製**

如果objective-c的物件轉成c/c++的**實際上最重轉成了c /c++的機構體。

那麼我們怎麼把oc的**轉換成c/c++的**呢?

終端進入到程式的目錄下:

輸入命令列

xcrun  -sdk  iphoneos  clang  -arch  arm64  -rewrite-objc  oc原始檔  -o  輸出的cpp檔案

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

複製**

然後機會生成乙個main-arm64.cpp的檔案 這裡面就是我們的c/c++的實現。

如果需要鏈結其他框架,使用-framework引數。比如-framework uikit

在生成main-arm64.cpp 內搜尋nsobject_impl

///> nsobject_impl

struct

nsobject_impl ;

複製**

nsobject的底層實現結構圖

上圖實際上nsobject物件中存在乙個isa指標,isa指標在64位系統中占用8個位元組,在32位的系統中占用4個位元組,目前用的是64位系統,所以在我們nsobject中isa指標會占用8個位元組。class isa的內部實現為結構體。

/// class 其實就是乙個指標  指向乙個結構體的指標

typedef

struct objc_class *class

複製**

///   建立並分配儲存空間

nsobject *obj = [[nsobject alloc]init];

複製**

假設我們nsobject物件分配了一塊儲存空間,假設之後8個位元組,在這8個位元組中我們只放了isa指標,假設我們的isa的位址為0x100400110,這個isa的位址就是結構體的位址。所以說obj的位址就是0x100400110。

#import 

#import

///> main

int main(int argc, char * ar**)

return0;}

複製**

然後我們用malloc_size的方法去檢視obj指標指向記憶體的大小 為16;

alloc本質呼叫的是allocwithzone。 在原始碼中搜尋allocwithzone

在底層**中間我們找到allocwithzone的底層方法。發現obj是由class_cerateinstance(cls,0)建立出來的。

然後我們在進入_class_createinstancefromzone(cls, extrabytes, nil);

進入後會看到calloc(1,size)的alloc的實現**,傳入了乙個size,size是instancesize(extrabytes)得到的,我們再次進入

規定物件的位元組至少是16個位元組, 當我們的分配的size值小於16是 會把size設定為16 我們size傳進來的就是alignedinstancesize() 就是我們傳進來的例項變數的大小 為8 所以當小於16的時候底層**中返回的就是16 , 所以分配的記憶體大小至少是16。

#import 

#import

///> student類

@inte***ce

student: nsobject

///> 實際底層的結構體 結構

//struct student_impl

@end

@implementation

student

@end

///> main

int main(int argc, char * ar**)

return0;}

複製**

思考: 如果我的student有三個成員變數 那麼會占用對少個位元組?

class_getinstancesize([student class]) 的輸出是多少?

malloc_size((__bridge const void *)stu的輸出是多少?

#import 

#import

///> student類

@inte***ce

student: nsobject

///> 實際底層的結構體 結構

//struct student_impl

@end

@implementation

student

@end

///> main

int main(int argc, char * ar**)

return0;}

複製**

isa:占用8個位元組,_no:占用4個位元組,_age:占用4個位元組, _gender:占用4個位元組, 不應該是一共占用了20個自己嗎?為什麼是24個呢?

為什麼會是24和32呢????窺探ios底層實現--oc物件的本質(二) - 掘金

iOS底層原理總結 OC物件的本質 二

ios底層原理總結 oc物件的本質 一 掘金 ios底層原理總結 oc物件的本質 二 掘金 ios底層原理總結 oc物件的分類 instance class meta calss物件的isa和superclass 掘金 ios底層原理總結 kvo kvc的本質 掘金 思考 如果我的student有三...

iOS底層原理總結 OC方法的本質

int main int argc,const char argv return 0 可以看出在我們進行lgperson初始化的時候,我們都知道會呼叫alloc,init.我這裡為了簡單只呼叫 new 但是底層不是像我們利用呼叫的,而是呼叫了乙個函式objc msgsend這就是我們訊息傳送的方法,...

iOS 類的底層原理

首先我們探索來例項物件 類物件 元類之間的關係,執行下面 可以看到class1 class2 class3列印結果一樣,我們是不是可以認為類物件只有乙個,元類是乙個虛擬的類由系統幫我們建立,是類物件所屬的類,而元類歸屬是根元類,根元類的歸屬是自身。例項物件 person p person alloc...