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下载地址



相关文章
|
1月前
|
存储 运维 安全
iOS加固原理与常见措施:保护移动应用程序安全的利器
iOS加固原理与常见措施:保护移动应用程序安全的利器
28 0
|
3月前
|
存储 运维 安全
iOS加固原理与常见措施:保护移动应用程序安全的利器
iOS加固原理与常见措施:保护移动应用程序安全的利器
38 0
|
7月前
|
C语言 索引
09-iOS之load和initialize底层调用原理分析
09-iOS之load和initialize底层调用原理分析
58 0
|
2月前
|
安全 前端开发 数据安全/隐私保护
【教程】 iOS混淆加固原理篇
本文介绍了iOS应用程序混淆加固的缘由,编译过程以及常见的加固类型和逆向工具。详细讨论了字符串混淆、类名、方法名混淆、程序结构混淆加密等加固类型,并介绍了常见的逆向工具和代码虚拟化技术。
|
3月前
|
安全 算法 前端开发
【完整版教程】iOS混淆加固原理篇
在iOS开发中,应用程序的安全性和保护显得尤为重要。由于iOS系统的开放性,一些逆向工具可以轻松地对应用程序进行反编译和分析,从而导致应用程序源代码、算法和敏感信息的泄露。为了保护应用程序的安全性,我们需要对应用程序进行混淆加固。本文将介绍iOS混淆加固的原理和常见的加固类型。
|
3月前
|
JSON 安全 数据安全/隐私保护
​iOS Class Guard github用法、工作原理和安装详解及使用经验总结
​iOS Class Guard github用法、工作原理和安装详解及使用经验总结
17 0
|
3月前
|
安全 数据安全/隐私保护 iOS开发
【iOS开发】iOS App的加固保护原理:使用ipaguard混淆加固
【iOS开发】iOS App的加固保护原理:使用ipaguard混淆加固
48 0
|
4月前
|
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一下链接就知晓了:
|
5月前
|
安全 数据安全/隐私保护 iOS开发
【iOS开发】iOS App的加固保护原理:使用ipaguard混淆加固 摘要
随着智能手机的普及,越来越多的用户使用iOS设备来处理日常任务,因此iOS应用程序的安全性变得越来越重要。为了防止应用程序被攻击或破解,开发人员需要采用一些保护措施来加固应用程序。本文将介绍一种使用ipaguard混淆加固的方法来保护iOS应用的安全。
|
5月前
|
运维 安全 数据安全/隐私保护
iOS加固原理与常见措施:保护移动应用程序安全的利器
随着移动应用的普及和用户对数据安全的关注度提高,iOS加固成为了很多开发者和企业的必备工具。那么,iOS加固是如何保护应用程序的安全性的呢? iOS加固是指对OS应用程序进行一系列的安全措施,以提高其抗逆向工程、反编译和破解的能力。下面将介绍iOS加固的原理和常见的加固措施。
iOS加固原理与常见措施:保护移动应用程序安全的利器