alloc的初始化流程

450 阅读2分钟

alloc的初始化流程

冬天的周末总是有着一股清冷的味道,泡杯茶,打开电脑,趁着周末的时间整理一些笔记,梳理梳理,今天花点时间梳理了下有关于对象创建的流程,接下来看看,单身狗是如何一步一步new出对象的,首先看流程图:

alloc流程图

嗯,看完流程图以后不知道该怎么描述了, 哈哈哈,总而言之,自己梳理梳理流程画画就大致清楚了,那么就整理下在梳理流程中的自己思考的一些问题吧。

1.为什么说当类首次调用+alloc方法时,调用的是objc_alloc函数实现?

当我尝试用符号断点的方式,尝试在汇编查看alloc,objc_rootAlloc,callAlloc的调用情况时,control+点击step into按钮后发现并不是我想象的调用顺序,objc_alloc是什么情况?不应该是alloc嘛?后来去查看源代码时发现在程序启动main函数调用之前,dyld调用_read_images函数加载相关Section信息时,在获取_getObjc2MessageRefs信息后,调用fixupMessageRef函数

  • fixupMessageRef
  • Repairs an old vtable dispatch call site.
  • vtable dispatch itself is not supported.

从源码注释来看是,为了修改一个vTable(虚函数表)的调用地址,所以当类首次初始化的时候,alloc的方法实现其实是指向了objc_alloc,当然,还有个问题是,在alloc初始化过程中,也调用过+alloc类方法,那么为什么这时候又是正常的调用呢?哈哈哈,这个问题暂时没有找到答案, 留着以后来更新。

2.在callAlloc函数中,canAllocFast方法为什么一直返回false呢?

先看源代码,会发现canAllocFast的返回值与宏定义FAST_ALLOC有关,当FAST_ALLOC为真时, 执行 return bits & FAST_ALLOC;反之,直接return false,当我们查看FAST_ALLOC宏定义的的时候,会发现#define FAST_ALLOC (1UL<<2) ,嗯,这不就是位运算,1向左移2位,转换成十进制的话也就是4, 那应该 return bits & FAST_ALLOC,为什么会直接返回false呢? 然后查询下周围有没有其他的条件,

嗯,这下我明白了,中间被别人拦着了,走不到#else,FAST_ALLOC就不会被定义,这不就直接返回false了嘛,哦多K,就是这样。

==============================================

PS:欢迎留言探讨交流,目的纯粹为了学习进步。