OC 对象原理(1)- 对象的建立(随记)

1、alloc 探索---查找alloc源码所在位置sass

先给出一段代码
复制代码
LGPerson *p1 = [LGPerson alloc];
    LGPerson *p2 = [p1 init];
    LGPerson *p3 = [p1 init];
    LGNSLog(@"%@ - %p",p1,&p1);
    LGNSLog(@"%@ - %p",p1,&p2);
    LGNSLog(@"%@ - %p",p1,&p3);
复制代码

打印结果:bash

<LGPerson: 0x6000016c6260> - 0x7ffee49c8178app

<LGPerson: 0x6000016c6260> - 0x7ffee49c8170post

<LGPerson: 0x6000016c6260> - 0x7ffee49c8168spa

从结果能够总结为,p1,p2,p3 指向同一个内存空间,但建立出来的三个对象的指针地址是不一样的。设计

以此咱们可能就会产生以下几个疑问:3d

一、为何会出现这个打印结果呢?指针

由于 alloc 建立实例对象的同时也申请了一块内存空间,p1,p2,p3是分配的3个对象的指针,所以 p1,p2,p3 属于同一个对象并都指向这块内存空间。调试

二、alloc 又是怎么实现的呢?code

咱们经过分析alloc源码来寻找这个问题的答案,有以下三种方式来知道alloc源码所在的动态库,libobjc.A.dylib:

1)第一种方式:真机调试,打断点

在如图所示打上断点,而后按住 ‘control’的同时点击箭头所指的按钮进入,再继续点击此按钮,直到出现 libobjc.A.dylib

2)第二种方式:选择Symbolic Breakpoint ,在Symbol这栏输入 alloc 也能获得想要的答案。

而后出现不少不少实现了alloc方法的断点,再次真机运行

此时再点击上图箭头所指的按钮以后也会出现

3)第三种方法:经过汇编 选择->Debug->Debug Workflow -> Always Show Disassembly,再次在真机上运行,此时会直接跳转到汇编界面

在其中咱们照样能够找到 objc_alloc,而后将断点下的此处,再按住 control 键,点击下图箭头所指按钮

一直按直到出现以下图所示,出现alloc所在的动态库名

三、建立对象的过程当中与init的关系是什么呢?

由上图 init 的源码可看出,init什么也没作,只是提供了一个初始化方法,方便咱们重写,由咱们本身随意发挥,工厂设计的模式

由上图得出new跟 alloc->init 同样的效果

2、alloc探索---下载并配置alloc所在的动态库开源的源码(objc)

源码下载地址:opensource.apple.com/tarballs/

源码编译调试参考点击

3、alloc探索--分析查看 alloc 源码流程

1)alloc 流程图

部分源码解释

calloc : 申请对象和开辟内存空间

initInstanceIsa :关联内存指针

2)申请内存空间(字节对齐)

size:申请的内存空间大小,对象自带内存大小 8 字节(Class isa)

a.对象内存空间规则 8 字节对齐(目的:提升 cpu 读取速度,以空间换取时间)

b.内存所占空间小于16字节时,最少16字节,为了防止读取或存储时越界

查看内存空间结构:

由上图可知:栈点指针起始位置为isa

打印指令:

x [对象名] :查看对象的存储空间,以16进制打印内存空间

x/[n]xg [对象名] : 以16 进制读取 n 个内存段

register read :读寄存器

随记:

x0:是第一个参数的传递者,也是返回值存储的地方(isa)

iOS 属于小端模式,内存地址倒着读

相关文章
相关标签/搜索