OC对象底层探索 — alloc创建对象

用于记录iOS底层学习,以备后续回顾

OC对象底层探索

  • alloc创建对象
  • 由字节对齐到对象内存大小探索
  • isa的初始化和指向分析

前言

  • alloc:iOS开发中为对象申请开辟内存的方法。

学习文档

iOS底层原理之alloc探索
iOS探索 alloc流程

配置环境+资料:

objc4-756.2源码 + Xcode11 + MacOS 10.15
官方源码下载地址
iOS_objc4-756.2 最新源码编译调试

一、探索alloc所在源码的三个方法

  • Control + Step into:objc_alloc
  • Symbolic Breakpoint 符号断点:libobjc.A.dylib`+[NSObject alloc]
  • 菜单Debug -> Debug Workflow -> Always show Disassembly 查看汇编代码

二、开始入坑

1、加断点探索源码在libobjc.A.dylib中


image.png

2、运行源码调试

  • 第一步
+ (id)alloc {
    return _objc_rootAlloc(self);
}
  • 第二步
id
_objc_rootAlloc(Class cls)
{
    return callAlloc(cls, false/*checkNil*/, true/*allocWithZone*/);
}
  • 第三步
// Call [cls alloc] or [cls allocWithZone:nil], with appropriate 
// shortcutting optimizations.
static ALWAYS_INLINE id
callAlloc(Class cls, bool checkNil, bool allocWithZone=false)
{
    if (slowpath(checkNil && !cls)) return nil;

#if __OBJC2__
    if (fastpath(!cls->ISA()->hasCustomAWZ())) {
        // No alloc/allocWithZone implementation. Go straight to the allocator.
        // fixme store hasCustomAWZ in the non-meta class and 
        // add it to canAllocFast's summary
        if (fastpath(cls->canAllocFast())) {
            // No ctors, raw isa, etc. Go straight to the metal.
            bool dtor = cls->hasCxxDtor();
            id obj = (id)calloc(1, cls->bits.fastInstanceSize());
            if (slowpath(!obj)) return callBadAllocHandler(cls);
            obj->initInstanceIsa(cls, dtor);
            return obj;
        }
        else {
            // Has ctor or raw isa or something. Use the slower path.
            id obj = class_createInstance(cls, 0);
            if (slowpath(!obj)) return callBadAllocHandler(cls);
            return obj;
        }
    }
#endif

    // No shortcuts available.
    if (allocWithZone) return [cls allocWithZone:nil];
    return [cls alloc];
}

主要对第三步进行详细流程分析,见流程图

alloc流程图.png

注:
8字节对齐:以空间换取时间,下一篇主要研究字节对齐

init、new探索

init:探索源码,仅仅是返回self,无实质作用,so仅仅是为了规范代码,提供接口层,工厂设计模式方便重写、自定义

- (id)init {
    return _objc_rootInit(self);
}

id
_objc_rootInit(id obj)
{
    // In practice, it will be hard to rely on this function.
    // Many classes do not properly chain -init calls.
    return obj;
}

new:探索源码 new = alloc + init

+ (id)new {
    return [callAlloc(self, false/*checkNil*/) init];
}

你可能感兴趣的:(OC对象底层探索 — alloc创建对象)