底层原理总结 — 对象
2020-02-08 本文已影响0人
踩坑小分队
1、一个NSObject对象占用多少内存?
平时编写的OC代码,底层都是C/C++代码

所以OC的面向对象都是基于C/C++的数据结构实现的,基于结构体的形式实现的。
实际操作:
1.1、将OC代码转化成C++代码
clang -rewrite-objc main.m -o main.cpp
将OC代码转化成相关架构下的C++代码
/**
* xcrun Xcode工具
* -sdk iphoneos 真机环境
* clang clang
* -arch arm64 架构是arm64
*/
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o main-arm64.cpp
当前可以看到,NSObject主要是一个 Class isa
,Class isa
其实对应的就是

对象的方法存在于另外一个地方。
1.2、对于一个自定义的对象,占用多大的空间呢?
@interface Person : NSObject
{
@public
int _age;
int _height;
}
@end
struct Person_IMPL {
struct NSObject_IMPL NSObject_IVARS;
int _age;
int _height;
};

16字节 = isa(8) + int(4) +int(4)
1.3、可以使用runtime的相关方法进行查看一个类占用多大的内存
#import <objc/runtime.h>
NSLog(@"Person 占用内存大小 -- %zu",class_getInstanceSize([Person class]));
2、查看对象的地址
方法1,通过debug调试工具查看:


方法2,通过LLDB查看:
(lldb) x/4xw 0x100605f90
0x100605f90: 0x000011a1 0x001d8001 0x0000000a 0x00000014
具体使用说明如下:

3、扩展:修改内存中的值
LLDB
memory write 内存地址 数值

4、扩展
在64bit的环境下,一个Person对象和一个Student对象占用多少内存空间?
// Person
@interface Person : NSObject
{
@public
int _age;
}
@end
@implementation Person
@end
// Student
@interface Student : Person
{
@public
int _height;
}
@end
@implementation Student
@end

代码分析:
struct NSObject_IMPL {
Class isa; // 8个字节
};
struct Person_IMPL {
struct NSObject_IMPL NSObject_IVARS; // 8个字节
int _age; // 4个字节
}; // 16个字节<内存对齐>
struct Student_IMPL {
struct Person_IMPL Person_IVARS; // 16个字节,空余四个
int _height; // 4个字节
}; // 16个字节<内存对齐>