美文网首页
汇编和源码配合分析alloc

汇编和源码配合分析alloc

作者: 扫地僧练级 | 来源:发表于2020-11-18 21:22 被阅读0次

    源码查找:苹果开源地址
    先下载objc4-xxx.tar

    开始

    全局搜索alloc {,找到底层实现方法

    20201118174435.jpg
    image.png

    最后看到的就是这些代码:

    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];
    }
    

    但是这么看各种if else是不是不爽,接下来通过汇编看看:

    • debug在alloc方法行加上断点,run
    • 如下图一次添加符号断点


      20201118173456.jpg
    • 终端执行register read (寄存器-简单理解 存储指针)如下:
      (注意:执行前将符号榜断点只保留alloc的)
    x0 = 0x00000001042d95e8  (void *)0x00000001042d95c0: ZKCPerson
            x1 = 0x00000001c568183f  
            x2 = 0x0000000000000001
            x3 = 0x000000016bb2de10
            x4 = 0x0000000000000010
            x5 = 0x000000016bb2da1f
            x6 = 0x000000016bb2db10
            x7 = 0x0000000000000000
            x8 = 0x00000001c5681000  
            x9 = 0x0000000000000303
           x10 = 0x00000002420cce4f
           x11 = 0x0000000000000003
           x12 = 0x0000000000000003
           x13 = 0x0000000000000000
           x14 = 0x00000000000000f2
           x15 = 0x00000001cb12b198  (void *)0x00000001c568180f
           x16 = 0x21512c8188dbe2e4 (0x0000000188dbe2e4) libobjc.A.dylib`+[NSObject alloc]
           x17 = 0x0000000188dbe2e4  libobjc.A.dylib`+[NSObject alloc]
           x18 = 0x0000000000000000
           x19 = 0x0000000000000000
           x20 = 0x0000000135e0a9d0
           x21 = 0x00000001d7236000  _MergedGlobals.9 + 24
           x22 = 0x00000001c5681f05  
           x23 = 0x0000000000000001
           x24 = 0x0000000000000001
           x25 = 0x00000001d4346000  UIKitCore`UIKeyboardSquishTransition._useInteractiveOpacity
           x26 = 0x0000000135e08a10
           x27 = 0x00000002834e6c40
           x28 = 0x00000001c568b55a  
            fp = 0x000000016bb2dc80
            lr = 0x00000001042d5e30  001`-[ViewController viewDidLoad] + 108 at ViewController.m:21:21
            sp = 0x000000016bb2dc00
            pc = 0x0000000188dbe2e4  libobjc.A.dylib`+[NSObject alloc]
          cpsr = 0x40000000
    
    因为OC方法有两个默认参数:
    1. id self
    2. _cmd 当前方法的selector
    所以可以执行以下命令:只读x0 register read x0,结果如下:

    (x0 第一个参数 -返回的时候 返回值的存储地方)

    x0 = 0x00000001042d95e8 (void *)0x00000001042d95c0: ZKCPerson

    继续执行: po 0x00000001042d95e8

    po 0x00000001042d95e8
    ZKCPerson

    可以看到现在还没指针(alloc-申请空间-给指针地址)

    • 增加符号断点_objc_rootAllocWithZone 进入后查看如下图:
    20201118210836.jpg

    在retab(返回对象)前增加断点,继续,执行register read x0

    x0 = 0x0000000282f6c000

    继续执行 po 0x0000000282f6c000

    <ZKCPerson: 0x282f6c000>

    可以看见现在person有了指针0x282f6c000

    未完待续,先关注一波。。。

    相关文章

      网友评论

          本文标题:汇编和源码配合分析alloc

          本文链接:https://www.haomeiwen.com/subject/rhbciktx.html