iOS-底层原理 04:NSObject的alloc 源码分析

简介: iOS-底层原理 04:NSObject的alloc 源码分析

主要NSObject中的alloc是与自定义类的alloc源码流程的区别,以及为什么NSObject中的alloc不走源码工程。


上一篇文章中分析了alloc的源码,这篇文章是作为对上一篇文章的补充,去探索为什么NSObject的alloc方法不走源码工程。


NSObject的alloc无法进入源码的问题


  • 首先在objc4-781可编译源码中的main函数中增加一个NSObject定义的对象,NSObject 和 LGPersong同时加上断点

image.png

image


  • alloc的源码实现中加一个断点,同时需要暂时关闭断点

image.png


  • 运行target,断点断在NSObject部分,打开alloc源码的断点,然后继续执行,会出现以下这种现象


探索Why


【第一步】探索[NSObject alloc]走的是哪步源码


接下来,我们就来探索为什么NSObject的alloc会出现这种情况,首先,


  • 打开Debug --> Debug Workflow --> 勾选 Always Show Disassemly,开启汇编调试
  • 关闭源码的断点,只留main中的断点,重新运行程序,然后通过下图的汇编可以发现NSObject并没有走 alloc源码,而是走的objc_alloc

image.png

image



  • 然后关闭汇编调试,在全局搜索 objc_alloc,在objc_alloc中加一个断点,先暂时关闭,


image.png


  • 重新运行进行调试,断住,然后打开objc_alloc的断点,发现会进入objc_alloc的源码实现,此时查看 clsNSObject

image.png


【第二步】探索 NSObject 为什么走 objc_alloc?


首先,我们来看看 NSObject 与 LGPerson的区别


  • NSObject 是iOS中的基类,所有自定义的类都需要继承自NSObject
  • LGPerson继承NSObject类的,重写NSObject中的alloc方法

然后根据第一步中汇编的显示,可以看出,NSObjectLGPerson 都调用了objc_alloc,所以这里就有两个疑问

  • 为什么NSObject 调用alloc方法 会走到 objc_alloc 源码?
  • 为什么LGPerson中的alloc走两次?即调用了alloc,进入源码,然后还要走到 objc_alloc


LGPerson中alloc 走两次 的 Why?


  • 首先,需要在源码中调试,在mainLGPerson加断点,断在LGPerson,再在allocobjc_alloccalloc 源码加断点,运行demo,会断在objc_alloc源码中(重新运行前需要暂时关闭源码中的所有断点)

image.png

  • 继续运行,发现LGPerson 第一次的alloc会走到 objc_alloc --> callAlloc方法中最下方的objc_msgSend,表示向系统发送消息

image.png



以下是第二次走到calloc方法中的调用堆栈情况

image.png所以由上述调试过程可以得出,LGPerson两次的原因是首先需要去查找sel,以及对应的imp的关系,当前需要查找的是 alloc 的方法编号,但是为什么会找到objc_alloc?这个就需要问系统了,肯定是系统在底层做了一些操作。请接着往下看


NSObject中alloc 走到 objc_alloc 的 why?


这部分需要通过 LLVM源码(即llvm-project) 来分析


准备工作:首先需要一份llvm源码


  • 在llvm源码中搜索objc_alloc


image.png


  • 搜索shouldUseRuntimeFunctionForCombinedAllocInit,表示版本控制

image.png


  • 搜索tryEmitSpecializedAllocInit,非常著名的特殊消息发送,在这里也没有找到 objc_alloc

image.png


  • 继续尝试,开启上帝视角,通过alloc字符串搜索,如果还找不到,还可以通过omf_alloc:找到tryGenerateSpecializedMessageSend,表示尝试生成特殊消息发送

image.png

然后在这个case中可以找到调用alloc,转而调用了objc_objc的逻辑,其中的关键代码是EmitObjCAlloc

image.png

image


  • 跳转至EmitObjCAlloc的定义可以看到alloc 的处理是调用了 objc_alloc

image.png

由此可以得出 NSObject中的alloc 会走到 objc_alloc,其实这部分是由系统级别的消息处理逻辑,所以NSObject的初始化是由系统完成的,因此也不会走到alloc的源码工程中


总结


总结下NSObject中alloc 和自定义类中alloc的调用流程


NSObject


image.png


自定义类

image.png

自定义类 alloc源码流程

相关文章
|
6月前
|
存储 运维 安全
iOS加固原理与常见措施:保护移动应用程序安全的利器
iOS加固原理与常见措施:保护移动应用程序安全的利器
91 0
|
6月前
|
存储 运维 安全
iOS加固原理与常见措施:保护移动应用程序安全的利器
iOS加固原理与常见措施:保护移动应用程序安全的利器
146 0
|
C语言 索引
09-iOS之load和initialize底层调用原理分析
09-iOS之load和initialize底层调用原理分析
89 0
|
存储 缓存 监控
iOS 底层原理39:Instruments系列(一)Instruments介绍
iOS 底层原理39:Instruments系列(一)Instruments介绍
1924 0
iOS 底层原理39:Instruments系列(一)Instruments介绍
|
6月前
|
安全 前端开发 数据安全/隐私保护
【教程】 iOS混淆加固原理篇
本文介绍了iOS应用程序混淆加固的缘由,编译过程以及常见的加固类型和逆向工具。详细讨论了字符串混淆、类名、方法名混淆、程序结构混淆加密等加固类型,并介绍了常见的逆向工具和代码虚拟化技术。
|
6月前
|
安全 算法 前端开发
【完整版教程】iOS混淆加固原理篇
在iOS开发中,应用程序的安全性和保护显得尤为重要。由于iOS系统的开放性,一些逆向工具可以轻松地对应用程序进行反编译和分析,从而导致应用程序源代码、算法和敏感信息的泄露。为了保护应用程序的安全性,我们需要对应用程序进行混淆加固。本文将介绍iOS混淆加固的原理和常见的加固类型。
|
6月前
|
JSON 安全 数据安全/隐私保护
​iOS Class Guard github用法、工作原理和安装详解及使用经验总结
​iOS Class Guard github用法、工作原理和安装详解及使用经验总结
99 0
|
6月前
|
安全 数据安全/隐私保护 iOS开发
【iOS开发】iOS App的加固保护原理:使用ipaguard混淆加固
【iOS开发】iOS App的加固保护原理:使用ipaguard混淆加固
87 0
|
运维 安全 数据安全/隐私保护
iOS加固原理与常见措施:保护移动应用程序安全的利器
随着移动应用的普及和用户对数据安全的关注度提高,iOS加固成为了很多开发者和企业的必备工具。那么,iOS加固是如何保护应用程序的安全性的呢? iOS加固是指对OS应用程序进行一系列的安全措施,以提高其抗逆向工程、反编译和破解的能力。下面将介绍iOS加固的原理和常见的加固措施。
iOS加固原理与常见措施:保护移动应用程序安全的利器
|
11月前
|
JSON 安全 数据安全/隐私保护
​iOS Class Guard github用法、工作原理和安装详解及使用经验总结
iOS Class Guard是一个用于OC类、协议、属性和方法名混淆的命令行工具。它是class-dump的扩展。这个工具会生成一个symbol table,这个table在编译期间会包含进工程中。iOS-Class-Guard能有效的隐藏绝大多数的类、协议、方法、属性和 实例变量 名。iOS-Class-Guard不是应用安全的最终解决方案,但是它绝对能让攻击者更难读懂你的程序。iOS-Class-Guard会加大代码分析和runtime检查的难度,这个工具可以认为是一个简单基础的混淆方法。由于OC的架构决定了iOS应用程序的剖析相当简单,check out一下链接就知晓了: