oc对象本质

一个NSObject 对象占多少内存
NSObject *obj = [NSObject new];

struct NSObject_IMPL {
    Class isa;
};

// Class的定义
typedef struct object_class *Class;

一个NSObject对象所占用的内存是16个字节(isa 只占8字节)。为什么会分配16个字节呢?我们可以去objc4源码看看alloc方法(在NSObject.mm文件中)的调用流程:
alloc-->_objc_rootAlloc()-->callAlloc()-->class_createInstance()-->_class_createInstanceFromZone()

_class_createInstanceFromZone()函数中调用了instanceSize()来确定一个对象要分配的内存的大小,其函数实现如下:

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;
    }

可以看到给一个对象分配内存的大小最小为16(这是系统硬性规定)。另外要注意的是一个实例对象占用多少内存和类中是否有方法是没有关系的,因为类中的方法并不存放在实例对象中(类中的方法存放在类对象的数据结构中)
那如果一个对象的内存占超过16字节会怎么样呢?

比如一个 Person 对象 有age height weight 三个成员变量

@interface Person : NSObject

@property (nonatomic , assign) int age;
@property (nonatomic , assign) int weight;
@property (nonatomic , assign) int height;
@end

此时的内存占用应该是 isa(8字节)、age(4字节)和height(4字节)和weight(4字节)此时应该是20字节 但是实际打印确是32字节

Person *person = [Person new];
NSLog(@"%zd",malloc_size((__bridge const void *)(person)));

原因是因为 iOS的内存字节对齐,其结果就是系统给一个对象分配的内存大小都是16的倍数。所以系统给一个自定义类的实例对象分配内存时,先计算类的所有成员变量(包括父类以及整个继承链的成员变量)的大小size,如果size刚好是16的倍数,那分配的内存的大小就是size;如果size不是16的倍数,那就将size补齐到刚好是16的倍数为止,补齐后的结果就是实际分配的内存大小。(结构体内存对齐字节数是8,OC对象内存对齐字节数是16)
内存占用和对象的方法无关,原因是对象数据结构不存储方法

对象的数据结构是什么样的呢?

你可能感兴趣的:(oc对象本质)