Object

对象的创建

2020-08-25  本文已影响0人  小溜子

1.OC对象是什么?

从源码分析

typedef struct objc_class *Class;
typedef struct objc_object *id;

objc.h

/// Represents an instance of a class.
// objc_object 的声明
struct objc_object {
    Class _Nonnull isa  OBJC_ISA_AVAILABILITY;
};

objc-private.h:

// objc_object 的实现
struct objc_object {
private:
    isa_t isa;
以下是一些函数,省略

objc-private.h:
...
}

// isa_t的定义,一个联合体,值为cls或者bits
union isa_t {
    isa_t() { }
    isa_t(uintptr_t value) : bits(value) { }

    Class cls;
    uintptr_t bits;
#if defined(ISA_BITFIELD)
    struct {
        ISA_BITFIELD;  // defined in isa.h
    };
#endif
};

其中uintptr_t是一个unsigned long类型,定义如下

typedef unsigned long           uintptr_t;

objc-runtime-new.h :

struct objc_class : objc_object {
    // Class ISA;
    Class superclass;
    cache_t cache;             // formerly cache pointer and vtable
    class_data_bits_t bits;    // class_rw_t * plus custom rr/alloc flags
    以下是一些函数,省略
    ...
}

2.OC对象包含什么?

我们已经知道了OC对象是一个objc_object类型的结构体,里面包含一个联合体isa,那么isa究竟是什么?

3.对象所占的内存空间

关于对象所占的内存空间,严格上讲是对象的指针所指向的结构体所占的内存空间。
系统提供了2个api获取有关对象内存空间的大小,我们看看如下例子:

创建Person继承NSObject:
Person.h

@interface Person : NSObject

@end

Person.m

@implementation Person

@end

我们在main.m中添加

Person *person = [Person alloc];
FHLog(@"class_getInstanceSize: is %ld ",class_getInstanceSize([person class]));
FHLog(@"malloc_size:%ld ",malloc_size((__bridge const void*)person));

log打印如下:
class_getInstanceSize: is 8
malloc_size:16
class_getInstanceSize和malloc_size究竟代表什么呢?

3.1class_getInstanceSize

从源码分析,相关的源码如下:

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

// Class's ivar size rounded up to a pointer-size boundary.
// 类的实例对象的成员变量的大小
uint32_t alignedInstanceSize() {
    return word_align(unalignedInstanceSize());
}

// 相当于(x+7)>>3 <<3,保证>=8且按8的倍数对齐
static inline uint32_t word_align(uint32_t x) {
    return (x + WORD_MASK) & ~WORD_MASK;
}

#   define WORD_MASK 7UL

// May be unaligned depending on class's ivars.
// 根据类的实例变量可能会进行内存对齐处理
uint32_t unalignedInstanceSize() {
    assert(isRealized());
    return data()->ro->instanceSize;
}

3.2mallocSize

id
_class_createInstanceFromZone(Class cls, size_t extraBytes, void *zone, 
                              bool cxxConstruct = true, 
                              size_t *outAllocatedSize = nil)
{
.....
    // 1.根据extraBytes计算对象的内存空间大小
    size_t size = cls->instanceSize(extraBytes);
    ···
    // 2.根据计算的size为obj申请分配内存
    obj = (id)calloc(1, size);
.....
}

其中cls->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;
}

我们为改动Person测试如下:
Person.h

@interface Person : NSObject

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

@end

输出:
class_getInstanceSize: is 16
malloc_size:16

Person.h

@interface Person : NSObject

@property (nonatomic, assign) int age;
@property (nonatomic, assign) int height;
@property (nonatomic, assign) bool isHealthy;

@end

输出:
class_getInstanceSize: is 24
malloc_size:32

与我们的分析一致。

4.#总结

上一篇 下一篇

猜你喜欢

热点阅读