一个 Person 对象、一个 Student 对象占用多少内存空间?
Person 和 Student 对象实际占用内存 16bytes,系统分配内存也是 16bytes。(注:这里实际占用为 16bytes 是因为结构体内存对齐)
- 系统分配了16个字节给NSObject对象(通过
**malloc_size**函数获得)- NSObject对象内部只使用了8个字节的空间(可以通过
**class_getInstanceSize**函数获得)
OC对象的本质
Objective-C 代码的底层都是通过 C/C++ 实现,所以 Objective-C 面向对象是基于 C/C++ 数据结构实现。 下图为OC语言转换成机器语言的几个过程。

通过终端指令:(注:如果需要链接其他框架,使用 -framework 参数。)
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o main_arm64.cpp
// 将 OC 代码转为 C++ 代码,得 NSObject 底层结构:struct NSObject_IMPL {Class isa;};// Class 是一个指向对象的结构体指针typedef struct objc_class *Class;
内存大小分配
所以 NSObject 是一个结构体,初始内部只有一个指向对象的结构体指针 isa。 由于 iOS 为64位系统,所以一个指针占 8bytes( 1byte = 8bit ),但是实际上系统给它分配了 16bytes 的内存空间。
NSLog(@"%zd",class_getInstanceSize([NSObject class])); //实例对象的成员所占用的大小 8bytes(实际使用的)NSLog(@"%zd",malloc_size((__bridge const void *)(obj))); //整个结构体占用的是 16bytes(实际分配的)
size_t instanceSize(size_t extraBytes) {size_t size = alignedInstanceSize() + extraBytes;// CF requires all objects be at least 16 bytes.if (size < 16) size = 16;return size;}
对象类型
Instance对象 & Class对象 & Meta-Class对象
Instance 对象(实例对象)
| > Instance 对象在内存中存储的信息包括 |
- isa 指针
- 其他成员变量
| | |Class 对象(类对象)
|Meta-Class 对象(元类对象)
| | 每个类在内存中有且仅有一个 Class 对象。
Class 对象在内存中存储的信息包括:
| 每个类在内存中也是有且仅有一个 Meta-Class 对象。
objectMetaClass 是 NSObject 的 meta-class 对象(元类对象)Meta-Class 对象在内存中存储的信息包括:
|
| ```cpp
Class objectMetaClass = object_getClass([NSObject class]); // Runtime API
// 注:以下获取的是 objectClass 是 Class 对象,并不是 Meta-Class 对象 Class objectClass = [[NSObject class] class];
| || **Class、Meta-Class 对象的本质结构都是 struct objc_class**<br /> | || <br />- **Instance 的 isa 指向 Class**。当调用对象方法的时,通过 Instance 的 isa指针找到 Class,最后找到 **对象方法** 的实现进行调用。<br />- **Class 的 isa 指向 Meta-Class**。当调用对象方法的时,通过 Class 的 isa指针找到 Meta-Class,最后找到 **类方法** 的实现进行调用。<br /> || --- ||  || <br />- Instance 调用对象方法的轨迹:**isa 找到 Class,方法不存在,就通过superclass 找父类**。<br />- Class 调用类方法的轨迹:**isa 找 Meta-Class,方法不存在,就通过 superclass 找父类**<br /> || --- ||  |**对象的isa指针指向哪里?**> - instance对象的isa指向class对象> - class对象的isa指向meta-class对象> - meta-class对象的isa指向基类的meta-class对象**OC的类信息存放在哪里?**> - 对象方法、属性、成员变量、协议信息,存放在class对象中> - 类方法,存放在meta-class对象中> - 成员变量的具体值,存放在instance对象<a name="ctuyJ"></a>## super的本质<a name="xBy3C"></a>## <a name="AHCWJ"></a>## 窥探 struct objc_class 的结构[objc4源码下载](https://opensource.apple.com/tarballs/objc4/)> #include <runtime.h>```cppstruct objc_class {Class _Nonnull isa OBJC_ISA_AVAILABILITY;};
include
typedef struct objc_class *Class;/// 实例类struct objc_object {Class _Nonnull isa OBJC_ISA_AVAILABILITY;};
include
// Class 类struct objc_class : objc_object {Class superclass;cache_t cache; // 方法缓存class_data_bits_t bits; // 用于获取具体的类信息...};
include
struct class_rw_t {uint32_t flags;Class firstSubclass;Class nextSiblingClass;explicit_atomic<uintptr_t> ro_or_rw_ext;...public:...const class_ro_t *ro() const {...}const method_array_t methods() const {...} // 方法列表const property_array_t properties() const {...} // 属性列表const protocol_array_t protocols() const {...} // 协议列表}
include
struct class_ro_t {uint32_t flags;uint32_t instanceStart;uint32_t instanceSize; // instance 对象占用的内存空间#ifdef __LP64__uint32_t reserved;#endifunion {const uint8_t * ivarLayout;Class nonMetaclass;};explicit_atomic<const char *> name; // 类名void *baseMethodList;protocol_list_t * baseProtocols;const ivar_list_t * ivars; // 成员变量列表const uint8_t * weakIvarLayout;property_list_t *baseProperties;...}

