iOS底层之alloc流程

调用alloc方法底层流程

  1. 调用alloc方法
    FCPerson *p = [FCPerson alloc].
  2. 调用alloc方法时,llvm编译阶段会对alloc方法进行拦截,不会按正常流程调用_objc_rootAlloc,而是会先调用objc_alloc,并对其进行特殊处理及标记,然后进入到callAlloc方法中
  3. callAlloc 代码如下:
#if __OBJC2__
    if (slowpath(checkNil && !cls)) return nil;
    if (fastpath(!cls->ISA()->hasCustomAWZ())) {
        return _objc_rootAllocWithZone(cls, nil);
    }
#endif

    // No shortcuts available.
    if (allocWithZone) {
        return ((id(*)(id, SEL, struct _NSZone *))objc_msgSend)(cls, @selector(allocWithZone:), nil);
    }
    return ((id(*)(id, SEL))objc_msgSend)(cls, @selector(alloc));

第一次走到callAlloc时,不会走到return _objc_rootAllocWithZone(cls, nil);,而是通过return ((id(*)(id, SEL))objc_msgSend)(cls, @selector(alloc));对cls重新发送alloc消息。第二次调用alloc方法时,系统会判断对象已经经过特殊处理,可以走正常流程,则依次调用_objc_rootAlloc, callAlloc,最终走到OBJC2中的_objc_rootAllocWithZone

  1. _objc_rootAllocWithZone中会调用核心方法_class_createInstanceFromZone:
  • 通过instanceSize计算对象开辟的内存大小。对象的内存大小取决于对象拥有的成员变量和属性。当对象没有成员变量时,对象属性只有isa(继承于NSObject):Class isa OBJC_ISA_AVAILABILITY;Class isa为结构体指针(struct objc_class *Class),大小为8,通过内存储存条件if (size < 16) size = 16决定了一个对象大小最小为16。
    成员变量内存相加的结果为unalignedInstanceSize, 根据内存对齐算法将unalignedInstanceSize 对齐:size_t size = alignedInstanceSize() + extraBytes;,具体对齐算法请见iOS内存对齐算法解析
  • 然后使用isa将FCPersonobj进行绑定:
 obj->initInstanceIsa(cls, hasCxxDtor);

isa绑定过程可见对象本质 & isa解析

  1. 整体流程图:


    alloc流程
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。