当前位置: 首页 > news >正文

【iOS】alloc的实际流程

目录

前言

为什么不按源码流程调用?

alloc的调用流程


前言

在之前的博客中我们有学习到过alloc的底层原理,沿着源码一步步找到了alloc的调用链——alloc—>_objc_rootAlloc—>callAlloc—>_objc_rootAllocWithZone—>_class_createInstanceFromZone,但其实在实际的alloc过程中,并不是这个调用流程,如果对NSObject的alloc加上断点调试就会发现,alloc流程并没有进入源码,接下来我们来探究一下为什么会这样以及真实的调用流程。

为什么不按源码流程调用?

在实际运行中,[NSObject alloc][MyClass alloc] 这类调用通常不会真正进入 libobjc 的源码层(比如 _objc_rootAlloc,而是走了更加高效的底层路径,这是由于 Apple 对运行时做了大量优化(比如汇编级别快速路径、ISA-optimized fast path)来避免频繁进入 C 层函数。

1.对于非NSObject类, objc_msgSend是汇编函数,非普通 C 函数

  • 它大多数时候在汇编层 直接查找 IMP 并跳转执行,不会进入 Objective-C runtime 的 C 函数实现。

  • 也就是说,objc_msgSend(obj, @selector(alloc)) 通常直接跳到了元类中的 +alloc 的 IMP。(这里涉及到后面cache_t的方法缓存,如果命中了Cache,就不会走完整的流程)

  1. 对于NSObject, 是基础类,系统做了特殊优化

  • 对于 NSObject和一些常见类,Apple 使用了 汇编级别的 fast path,这意味着即便你打断点试图进入 _objc_rootAlloc,你可能根本进不去。

  • 常见的“未命中源码”的情况说明使用的是缓存或特殊入口。

alloc的调用流程

通过调用alloc后的堆栈详情我们就可以发现,无论是NSObject类还是自定义类,调用alloc方法最开始走的都是objc_alloc而不是objc_rootAlloc。这是因为消息转发时系统在底层帮我们转发到了objc_alloc。我们来看看objc_alloc的源码实现

可以发现其实他和objc_rootAlloc的实现是一样的,调用callAlloc。

回顾之前callAlloc的实现

可以看到callAlloc中分为几个分支来处理

对于NSObjcet类,初始化在llvm编译时就已经初始化好了,因此缓存中已经有alloc/allocWithZone方法了,hasCustomAWZ()为false,那么!cls->ISA()->hasCustomAWZ()就为true。

因此NSObjcet在此时会进入_objc_rootAllocWithZone并调用_class_createInstanceFromZone,后面的步骤就和之前说的一样了,这就是为什么NSObjct没有走alloc方法

而对于自定义类,初次创建时没有默认的alloc/allocWithZone实现,所以继续向下执行进入到消息发送流程,消息转发时会向父类找,最终找到NSObjcet的alloc并调用,即[NSObjcet alloc],这时会来到_objc_rootAlloc,进入后再次调用callAlloc,这次调用的是NSObject类的,缓存中存在alloc/allocWithZone实现,就接着走_objc_rootAllocWithZone方法,后面步骤也就和之前一样了。所以自定义类在调用alloc时会走两次callAlloc

总结一下,NSObjcet的调用链如下图:

自定义类的调用链如下图:

相关文章:

  • 106. 从中序与后序遍历序列构造二叉树
  • 本地化部署HomeAssistant语音助手并接入DeepSeek
  • 波导模型(表面等离激元、石墨烯等)本征模式分析、各种类型波导传输效率求解
  • JAVA数组题(7)
  • STL - stack 和 queue 及容器适配器模式的介绍
  • C++11(2)
  • 大语言模型三大演进方向:记忆增强、工具集成与多模态突破
  • 插件双更新:LeetCode 刷题支持正式上线,JetBrains IDE 插件持续升级!
  • 《从零开始入门递归算法:搜索与回溯的核心思想 + 剑指Offer+leetcode高频面试题实战(含可视化图解)》​
  • 机器学习第十三讲:独热编码 → 把“红黄蓝“颜色变成001/010/100的数字格式
  • 将.pt文件执行图像比对
  • 赛博放生:用数字技术重构心灵仪式
  • 跨系统数据烟囱如何破局?豪森智源HSMES重构制造协同新范式‌
  • AI全域智能监控系统重构商业清洁管理范式——从被动响应到主动预防的监控效能革命
  • 数据科学和机器学习的“看家兵器”——pandas模块 之四
  • 上线前测试组发现问题较多。开发总结
  • 数控机床控制单元技术方案:基于EFISH-SCB-RK3588/SAIL-RK3588的赛扬N100/N150国产化替代全场景解析
  • c++从入门到精通(四)--动态内存,模板与泛型编程
  • 小白入门:GitHub 远程仓库使用全攻略
  • 印度全印度游戏联合会(AIGF)介绍与用途
  • 马上评|“衣服越来越难买”,对市场是一个提醒
  • 习近平会见哥伦比亚总统佩特罗
  • GDP逼近五千亿,向海图强,对接京津,沧州剑指沿海经济强市
  • 观众走入剧院空间,人艺之友一起“再造时光”
  • 18世纪“精于剪切、复制、粘贴”的美国新闻界
  • 75万采购防火墙实为299元路由器?重庆三峡学院发布终止公告:出现违法违规行为