OC对象的内存空间

91 阅读1分钟

OC对象的本质是结构体

struct NSObject_IMPL {
    Class isa;
};
  1. 一个OC对象最少占用几个字节?
NSObject *obj = [[NSObject alloc] init];
// >> 8
NSLog(@"%zd", class_getInstanceSize([NSObject class]));
// >> 16
NSLog(@"%zd", malloc_size(( **__bridge** **const** **void** *)obj));

可以通过代码打印出来,发现系统实际分配了16个字节,但是对象只用到了8个字节。

  1. 继续思考:那么为什么这样呢?
size_t class_getInstanceSize(Class cls)
{
    if (!cls) return 0;
    //Class's ivar size rounded up to a pointer-size boundary.
    return cls->alignedInstanceSize();
}

这个其实是分配的成员变量所分配的内存大小,这个值是:8

接下来看下alloc的源码:

//Call [cls alloc] or [cls allocWithZone:nil], with appropriate
// shortcutting optimizations
id
_objc_rootAllocWithZone(Class cls, malloc_zone_t *zone)
{
    id obj;

    if (fastpath(!zone)) {
        obj = class_createInstance(cls, 0);
    } else {
        obj = class_createInstanceFromZone(cls, 0, zone);
    }

    if (slowpath(!obj)) obj = _objc_callBadAllocHandler(cls);
    return obj;
}

//接下来再看 class_createInstanceFromZone
size_t size;
size = cls->instanceSize(extraBytes);

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个字节,所以malloc_size的内存空间就是16;

3.那么继续看假如有属性的时候占用多少字节?

@interface Student : NSObject {
    @public
    int age;
    float wight;
}
//不要忘记实现Student
@implementation Student

@end

再通过打印发现

// >> 16
NSLog(@"%zd", class_getInstanceSize([Student class]));
// >> 16
NSLog(@"%zd", malloc_size(( **__bridge** **const** **void** *)obj));

得出结论: 对象InstanceSize是8,int、float分配的字节都是4,所以打印的都是16,如果超过16,malloc_size的大小也会跟着一块改变 那么思考一下,如果在Student里面再去添加一个NSString呢?打印出来的是什么呢?

答案是:class_getInstanceSize: 24, malloc_size:32