iOS底层原理:OC对象底层探索之alloc初探(一)

简介: iOS开发的小伙伴们对 [XXX alloc] init] 都不陌生,可以说 alloc 和 init 贯穿我们整个的开发过程中。那么在OC对象的底层,到底做了哪些操作呢?今天我们就来探索一下 alloc 底层的工作流程。

image.png

iOS开发的小伙伴们对 [XXX alloc] init] 都不陌生,可以说 allocinit 贯穿我们整个的开发过程中。那么在OC对象的底层,到底做了哪些操作呢?今天我们就来探索一下 alloc 底层的工作流程。

一、抛砖引玉


我们先来看一下下面这张图中的测试代码和打印结果:


image.png

从上面的打印结果来看,p、p1、p2对象的内存地址是一样的,但是p、p1、p2对象的指针地址(&p、&p1、&p2)是不同的。而pNew对象的内存地址和指针地址和p、p1、p2都不一样,很显然,pNew属于拥有另一块内存空间的另一个对象了。

由此我们暂时得出结论:

  • p、p1、p2对象的指针地址是不同的, 但是他们都指向同一内存空间;
  • alloc 可以开辟内存空间,而 init 不会;
  • p、p1、p2对象的指针地址&p > &p1 > &p2 > &pNew,说明栈区是由高到低连续开辟的
  • p 、pNew对象的内存地址p < pNew,说明堆区是由低到高开辟内存的

结合堆栈的知识 ,我画了下面👇这张图,帮助大家理解。


image.png


二、准备工作


通过上面我们可以发现,对象内存地址是通过 alloc 创建,我们看一下 alloc 是怎么实现的。

点击 alloc 方法进入 NSObject.h:


image.png


image.png


进入NSObject.h,我们再点击跳转,发现跳转不进去了,也就看不到alloc的实现了。难道我们就只能停在这里?就只能在外面蹭一蹭了吗?

NO,下面来介绍一下探索底层的三种方法,方便我们在探索底层源码的时候能够顺利的跟对方法(函数)的一个执行流程。

第一种:添加符合断点方式
  • 在工程中选择断点 --> 点击左下角"+" --> Symbolic Breakpoint


image.png

  • 比如我这里想知道alloc源码位置, 那么就输入alloc

image.png

  • 然后运行, 我们发现alloc的符号断点非常多,到底哪个才是我们想要的呢?

image.png


  • 接着我们还需要在想要执行的代码处增加一个普通断点,比如我们这里在JQPersonalloc处打上一个断点,然后将alloc符号断点先禁用


image.png

6.png

  • 运行程序,首先来到我们的普通断点[JQPerson alloc]处,然后我们将符号断点alloc启用,点击断点操作按钮进入下一步


image.png

image.png


到这里,我们可以看到alloc方法在libobjc.A.dylib库中(ps:libobjc.A.dylib是objc的系统库,感兴趣的小伙伴可以去苹果开源官网Open Source下载查看,注意:Open Source上下载下来的源码是不能直接编译和调试的,想要下载的objc源码可编译调试的小伙伴可以移步到我之前的文章iOS底层原理(一):苹果开源 objc4-818 源码项目的编译和调试


第二种: 断点 + step into方式


  • 我们先在要执行的代码打上断点,运行项目,来到断点位置


image.png

  • 然后按住control键,点击setp into一步一步查找,会看到如下结果


image.png


  • 最后再添加objc_alloc符号断点,点击Continue program execution继续执行


image.png

这里我们可以看到,断点进入了libobjc.A.dylib中的objc_alloc函数,由此可知alloc方法的源码在libobjc.A.dylib库中。


第三种: 汇编跟进方式


  • 首先,我们还是先在要执行的代码打上断点


image.png

  • 然后在Xcode菜单栏找到 Debug ==> Debug Workflow ==> Always Show Disassembly并选中(这里是启用汇编进行调试)


image.png

  • 运行项目,来到如下图的断点处

image.png


我们可以看到当前断点下面两行处,有个callq xxxx; symbol stub for objc_alloc,接着我们再添加一个objc_alloc符号断点, 点击Continue program execution继续执行(ps:这里解释一下:callq是汇编中的一个指令,代表这个这里即将要调用一个方法,symbol stub for objc_alloc翻译过来是objc_alloc的符号存根,也就是说objc_alloc是要调用的方法名)


image.png

好了,到此底层探索的三种方式就介绍完了,接下来我们步入正题吧!


三、alloc源码探索


好的,有了上面的探索方法,我们现在就拿 objc 源码项目来探索 alloc 的底层实现吧。

首先,打开之前编译好的 objc4-818.2 项目,需要的小伙伴可以参考我之前文章iOS底层原理(一):苹果开源 objc4-818 源码项目的编译和调试,到 Open Source 上下载源码自行编译,不想麻烦的也可以直接去 GitHub 上下载:JQObjc4-818.2BuildDebug

然后,找到 JQObjcBuildDemo 目录下创建一个JQPerson类。然后在main.m中添加如下代码:


image.png


注意: 这里 16、17行 分别有个断点,后面会用到!!!

我们从上面的底层探索方式中可以看到:[JQPerson alloc]在底层libobjc.A.dylib库中执行的objc_alloc方法,接下来我就来验证一下。

第1步:alloc 和 objc_alloc


  1. 点击alloc跳转到 objc 的源码中,搜索一下objc_alloc,然后分别在allocobjc_alloc处打上断点


image.png

image.png


  1. 然后,先将源码中allocobjc_alloc处的断点禁用,运行项目来到main.m中的断点处


image.png

  1. 接着,启用源码中allocobjc_alloc处的断点,点击下一步,这时会发现:断点来到了objc_alloc


image.png


这就验证了我们前面所讲的,alloc方法在底层libobjc.A.dylib库中执行的objc_alloc方法


  1. 再次点击下一步,惊奇的发现:断点来到了alloc方法处


image.png


那么为什么[JQPerson alloc]在底层会先走objc_alloc方法,再走alloc方法呢?按照我们在 objc 源码中看到的方法调用流程,应该是[JQPerson alloc] => alloc呀?


为了验证这个问题,我们需要请出YYDS(永远滴神):llvm源码(是苹果开源的系统级别的源码),看一看苹果是不是在这里面做了什么骚操作。llvm-project下载地址



相关文章
|
7月前
|
存储 运维 安全
iOS加固原理与常见措施:保护移动应用程序安全的利器
iOS加固原理与常见措施:保护移动应用程序安全的利器
95 0
|
7月前
|
存储 运维 安全
iOS加固原理与常见措施:保护移动应用程序安全的利器
iOS加固原理与常见措施:保护移动应用程序安全的利器
161 0
|
C语言 索引
09-iOS之load和initialize底层调用原理分析
09-iOS之load和initialize底层调用原理分析
99 0
|
7月前
|
安全 前端开发 数据安全/隐私保护
【教程】 iOS混淆加固原理篇
本文介绍了iOS应用程序混淆加固的缘由,编译过程以及常见的加固类型和逆向工具。详细讨论了字符串混淆、类名、方法名混淆、程序结构混淆加密等加固类型,并介绍了常见的逆向工具和代码虚拟化技术。
|
机器学习/深度学习 API iOS开发
iOS MachineLearning 系列(17)—— 几个常用的对象识别 CoreML 模型
上一篇文章中,我们介绍了几个官方的图片分类的模型,图片分类模型的应用场景在于将图片中最主要的事物进行识别,在已有的词库中找到最可能得事物。而对象识别则要更高级一些。再之前的文章,我们介绍过可以使用官方提供的API来进行矩形识别,文本识别,二维码识别以及人脸识别等,这类识别功能的特点是我们不仅可以将图片中的物体位置和尺寸分析出来,还可以对其进行类别的分类。
379 0
|
7月前
|
安全 算法 前端开发
【完整版教程】iOS混淆加固原理篇
在iOS开发中,应用程序的安全性和保护显得尤为重要。由于iOS系统的开放性,一些逆向工具可以轻松地对应用程序进行反编译和分析,从而导致应用程序源代码、算法和敏感信息的泄露。为了保护应用程序的安全性,我们需要对应用程序进行混淆加固。本文将介绍iOS混淆加固的原理和常见的加固类型。
|
7月前
|
JSON 安全 数据安全/隐私保护
​iOS Class Guard github用法、工作原理和安装详解及使用经验总结
​iOS Class Guard github用法、工作原理和安装详解及使用经验总结
109 0
|
7月前
|
安全 数据安全/隐私保护 iOS开发
【iOS开发】iOS App的加固保护原理:使用ipaguard混淆加固
【iOS开发】iOS App的加固保护原理:使用ipaguard混淆加固
101 0
|
运维 安全 数据安全/隐私保护
iOS加固原理与常见措施:保护移动应用程序安全的利器
随着移动应用的普及和用户对数据安全的关注度提高,iOS加固成为了很多开发者和企业的必备工具。那么,iOS加固是如何保护应用程序的安全性的呢? iOS加固是指对OS应用程序进行一系列的安全措施,以提高其抗逆向工程、反编译和破解的能力。下面将介绍iOS加固的原理和常见的加固措施。
iOS加固原理与常见措施:保护移动应用程序安全的利器
|
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一下链接就知晓了: