alloc源码流程

336 阅读2分钟

1.jpeg

alloc原理初探

  • [探索alloc的引入]

  • [alloc源码探索的三种方式]

  • [alloc做了什么事情]

  • [init做了什么事情]

  • [alloc的核心方法]

探索alloc的引入


    LGPerson *p2 = [p1 init];

    LGPerson *p3 = [p1 init];

    

    NSLog(@"%@-%p-%p",p1,p1,&p1);

    NSLog(@"%@-%p-%p",p2,p2,&p2);

    NSLog(@"%@-%p-%p",p3,p3,&p3);
    
    打印信息 
    **<LGPerson: 0x600000abc470>-0x600000abc470-0x7ffee2e850d8**
    
    **<LGPerson: 0x600000abc470>-0x600000abc470-0x7ffee2e850d0**
    
    **<LGPerson: 0x600000abc470>-0x600000abc470-0x7ffee2e850c8**

1.png

问题引入****3个不同地址指针同时指向同一片内存空间 alloc是不是开辟了内存 init是不是内存一样****

alloc源码探索的三种方式

1.下符号断点alloc直接跟流程

2.jpg

2.通过按住control - step into

3.通过汇编流程 ->查看源码出处。

3.jpg

**源码来源libobjc.A.dylib**

定位objc源码

苹果开源源码汇总: opensource.apple.com

这个地址用的更直接 opensource.apple.com/tarballs/

4.jpg

alloc流程图

5.png

源码分析

咋们下断点跟汇编

1.jpg

汇编实际开始是调用了objc_alloc 这里就引起了我们的思考,明明写的是alloc 为什么调用的确是objc_alloc 这里就不得不想到编译器LLVM给我们的代码做了相关的处理。 llvm下载地址:github.com/llvm/llvm-p…

2.jpg

大概意思就是给对象发送alloc消息LLVM会进行拦截判断是不是特殊的alloc方法如果是给发送的接受者标记并且把修改成调用objc_alloc->callAlloc->_objc_rootAllocWithZone

3.jpg

重新发送一次alloc消息

接下来流程如下看上面流程图

alloc做了什么事情?

4.jpg

1.计算成员变量所需要的字节大小并对齐

2.传入给calloc开辟类空间

3.类与isa绑定关联

一一分析 size = cls->instanceSize(extraBytes); 1634651083934.jpg

1634651538407.jpg

成员变量以8字节对齐

calloc我们下一章分析

obj->initInstanceIsa(cls, hasCxxDtor);

1634651983979.jpg

init底层做了什么

    return _objc_rootInit(self);
}
_objc_rootInit(id obj)
{
    
    return obj;
}

提供工厂方法初始化为开发人员提供一个构造方法的入口