iOS底層原理總結--OC對象的本質(一) - 掘金xcode
iOS底層原理總結--OC對象的分類:instance、class、meta-calss對象的isa和superclass - 掘金post
...spa
思考: 若是個人Student有三個成員變量 那麼會佔用對少個字節? (class_getInstanceSize([Student class]) 的輸出是多少? malloc_size((__bridge const void *)stu的輸出是多少? )
3d
#import <malloc/malloc.h>
#import <OBJC/runtime.h>
///> Student類
@interface Student: NSObject{
@public
int _no;
int _age;
int _gender;
}
///> 實際底層的結構體 結構
//struct Student_IMPL{
// Class isa,
// int _no,
// int _age;
// int _gender;
//}
@end
@implementation Student
@end
///> main
int main(int argc, char * argv[]) {
@autoreleasepool {
Student *stu = [[Student alloc]init];
stu->_no = 4;
stu->_age = 5;
stu->_gender = 1;
NSLog(@"%zd", class_getInstanceSize([Student class]));
NSLog(@"%zd", malloc_size((__bridge const void *)stu));
/**輸出結果 24 32 */
}
return 0;
}
複製代碼
可使用Xcode自帶的工具去查看 系統分配的內存和使用的內存狀況。指針
首先咱們須要拿到stu對象的內存地址: 調試
xcode控制檯經常使用指令: Xcode調試器LLDB - 掘金這裏咱們的內存地址爲:<Student: 0x600002746b60>code
而後選擇:Debug --> Degug Workflow --> View Memory 在下方的位置輸入咱們剛剛獲得的內存地址後就能夠了,stu的內存結構如上圖所示 直到紅線的位置都是stu所開闢的存儲空間,直到紅色數線後纔有了新的值, 在以前都是00值並且在內存中內存是連續的, 因此咱們能夠認爲,直到紅色豎線位置以前都是stu所分配的存儲空間 如上圖所示由上圖分析:咱們能夠得出 stu實際上在內存中分配了32個字節的內存空間 也就是 malloc_size() 所輸出的開闢內存空間的字節數。
cdn
class_getInstanceSize 顧名思義 獲取類的實例大小 isa佔用8個 + _no:4個 + _age4個 + _gender4個
@interface Student: NSObject{
@public
Class isa; ///> 8
int _no; ///> 4
int _age; ///> 4
int _gender; ///> 4
} /// 計算相加後 爲20個,
複製代碼
結構體存在一個內存對其的操做,這樣有利於CPU的訪問, 在CO中用到的內存對其的一條規則就是: 結構體爲了保證內存對其 最重的真用內存必定是佔用最大的一個變量的倍數, 在這裏咱們isa佔用了8個字節數, 因此雖然實際上只使用了20個字節,可是爲了保證內存對其的規則 因此使用了24個字節,
若是咱們有4個成員變量的話:
@interface Student: NSObject{
@public
Class isa; ///> 8
int _no; ///> 4
int _age; ///> 4
int _gender; ///> 4
int _height; ///> 4
} /// 計算相加後 爲24個,
複製代碼
咱們真用的內存仍是24,開闢依舊是32個字節。
若是在增長一個成員變量的話:
@interface Student: NSObject{
@public
Class isa; ///> 8
int _no; ///> 4
int _age; ///> 4
int _gender; ///> 4
int _height; ///> 4
int _weight; ///> 4
} /// 計算相加後 爲28個,
複製代碼
爲了保證內存對其因此大小爲32個字節,開闢依舊是32個字節。
malloc_size() 也運用了內存對其的 上篇文章中解釋了爲何給類的內存分配了16個字節, 因爲內存對其的緣由因此stu類分配了32個字節。