Skip to content

Latest commit

 

History

History
78 lines (55 loc) · 2.08 KB

12.第十二题.md

File metadata and controls

78 lines (55 loc) · 2.08 KB

12.一个 NSObject 对象占用多少内存空间?

结论:受限于内存分配的机制,一个 NSObject对象都会分配 16Bit 的内存空间。但是实际上在64位下,只使用了 8bit,在32位下,只使用了 4bit

首先NSObject对象的本质是一个NSObject_IMPL结构体。我们通过以下命令将 Objecttive-C 转化为 C\C++

// 如果需要连接其他框架,可以使用 -framework 参数,例如 -framework UIKit
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o main.cpp

通过将main.m转化为main.cpp 文件可以看出它的结构包含一个isa指针:

struct NSObject_IMPL {
    Class isa;
};

如果当前是继承自NSObjectPerson类,结构如下:

struct Person_IMPL {
    Class isa;
    // 自己的成员变量
    int _age;
    int _height;
};

or(参考上面 NSObject_IMPL 的结构)

struct Person_IMPL {
    struct NSObject_IMPL NSObject_IVARS;
    // 自己的成员变量
    int _age;
    int _height;
};

下面通过一个例子来验证一下以上的结论

初始化一个NSObject对象

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

导入运行时头文件 #import <objc/runtime.h>,利用 class_getInstanceSize 方法,传入实例的类,即可获取当前实例实际占用内存的大小

NSLog(@"object 实际占用内存大小为 %zd",class_getInstanceSize([object class]));
// 打印结果为 8

之后我们导入 #import <malloc/malloc.h>

NSLog(@"object 指针指向内存的大小为 %zd",malloc_size((__bridge const void *)object));
// 打印结果为 16

Class_getInstanceSize底层实现:对象在分配内存空间时,会进行内存对齐,所以在 iOS 中,分配内存空间都是 16字节 的倍数。如果存在继承关系,则需要父类的大小

size_t class_getInstanceSize(Class cls)
{
    if (!cls) return 0;
    return cls->alignedInstanceSize();
}

可以通过以下网址 :openSource.apple.com/tarballs 来查看源代码。