C0a73fa784f2b56e8655e73aa1edf898
iOS高级之美-OC对象底层下篇

一、前面篇章复习

很高兴优秀的你打开这一篇专栏,这一篇专栏我们还是承接 上一篇 继续分析!

上一篇我们分析到 alloc 的流程,通过一些特色技巧展开

  • LLDB分析
  • 汇编阅读
  • 源码调试
  • 符号断点

通过上面的方法我们锊出了,alloc的流程

这个流程分析的过程中,有一段非常重要的代码!我们抓住了两个核心重点!

static __attribute__((always_inline)) 
id
_class_createInstanceFromZone(Class cls, size_t extraBytes, void *zone, 
                              bool cxxConstruct = true, 
                              size_t *outAllocatedSize = nil)
{
    if (!cls) return nil;

    assert(cls->isRealized());

    // Read class's info bits all at once for performance
    bool hasCxxCtor = cls->hasCxxCtor();
    bool hasCxxDtor = cls->hasCxxDtor();
    bool fast = cls->canAllocNonpointer();

    size_t size = cls->instanceSize(extraBytes);
    if (outAllocatedSize) *outAllocatedSize = size;

    id obj;
    if (!zone  &&  fast) {
        obj = (id)calloc(1, size);
        if (!obj) return nil;
        obj->initInstanceIsa(cls, hasCxxDtor);
    } 
    else {
        if (zone) {
            obj = (id)malloc_zone_calloc ((malloc_zone_t *)zone, 1, size);
        } else {
            obj = (id)calloc(1, size);
        }
        if (!obj) return nil;
        // Use raw pointer isa on the assumption that they might be 
        // doing something weird with the zone or RR.
        obj->initIsa(cls);
    }

    if (cxxConstruct && hasCxxCtor) {
        obj = _objc_constructOrFree(obj, cls);
    }
    return obj;
}
  • obj = (id)calloc(1, size)
  • obj->initInstanceIsa(cls, hasCxxDtor)
  • 这两行代码应该直接决定了 alloc 的作用

二、展开分析alloc的意义

下面开始展开分析这两个核心内容

1: 创建指针,申请内存

经过 calloc 函数创建了一个指针,这个指针是怎么创建,这个源码按照我们上一节的探索思路很容易得到 :libmalloc 源码出处!

calloc()
  - malloc_zone_calloc(default_zone, num_items, size);
     - ptr = zone->calloc(zone, num_items, size);
     - default_zone_calloc()
        - nano_malloc()
        - void *p = _nano_malloc_check_clear(nanozone, size, 0);
            - size_t slot_bytes = segregated_size_to_fit(nanozone, size, &slot_key); // Note slot_key is set here
            - ptr = segregated_next_block(nanozone, pMeta, slot_bytes, mag_index);
  • 就在 segregated_next_block 不断递归去寻找合适的内存空间

  • 其中还有一个疑问点就是到底申请多少内存空间呢?

  • 其中我们通过size_t size = cls->instanceSize(extraBytes)得到传入 calloc 的大小为 40 (这个值是我们因为LGPerson 属性影响的)

@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) int age;
@property (nonatomic, assign) long height;
@property (nonatomic, strong) NSString *hobby;
  • 其中利用了字节对齐的原则 8字节对齐 ~ (x + WORD_MASK) & ~WORD_MASK
  • 其中 # define WORD_MASK 7UL

🤔那么我们40传进 calloc里面做了什么 ? 导致我们在外面malloc_size 输出 48 🤔

top Created with Sketch.