先抛出一个小问题,然后延伸引入接下来要说的

zuyuClass *z = [zuyuClass alloc];

zuyuClass *z1 = [z init];

zuyuClass *z2 = [z init];

NSLog(@”%p – %p – %p”,z,z1,z2);

思考一下是控制台的输出是怎么样的

思考过后代码试一下

z,z1,z2三个对象的地址是完全一样的

alloc 做了些什么?init 做了些什么?

OK我们现在正是开始今天的内容

想知道 alloc 都干了些什么.最简单的方式就是看源码对吧.来,咱们瞄一眼源码去

随便说说 alloc 和 init

1

继续往下

随便说说 alloc 和 init

2

继续

随便说说 alloc 和 init

3

好,到这里简单说一下,会走到红色选中的位置,为什么会走到这儿呢? 通过下符号断点,显示的汇编中看出来,这咱们就简单的一句带过,不详细说.

随便说说 alloc 和 init

简单说明

咱们继续往下

class_createInstance

随便说说 alloc 和 init

4

继续往下

随便说说 alloc 和 init

5

好了 划重点了开始

重点1.      size_t size = cls->instanceSize(extraBytes);     6518行

创建对象首先最重要的大家应该都知道啦  ,  内存 , 对吧. 这个 size 就是获取该对象需要多大的空间,从而进行字节对齐

(字节对齐简单来说就是 ,比如改对象需要12个字节, 那么就返回16字节 .如果该对象需要23个字节,那么就返回24字节 . 为什么要对齐?  玩过逆向,汇编或者研究过底层的朋友就比较理解这个,在这咱们就不多说了)

随便说说 alloc 和 init

5.1获取该对象所需要的空间

随便说说 alloc 和 init

5.2调用算法计算出所需要的内存空间

这是 alloc 做的第一件事 .计算并进行字节对齐.

咱们继续抛出一个问题,比如现在有个 zuyuClass 的类.  有NSString 类型的 name(8字节) 和 int 类型的 age(4字节) .根据字节对齐. 这个类的对象占用了多少字节的内存?

脑袋里边想着是16的,可以用代码输出一下 看一下 , 是24 .问题又来了 ,为什么是24个字节

重点2.        obj->initInstanceIsa(cls, hasCxxDtor)   6525行.

创建一个 isa.  isa 占用了8个字节 . 万物皆对象,对象皆有 isa

随便说说 alloc 和 init

对象皆有 isa

ok.这个时候大家是不是就以为zuyuClass在内存中就占用24个字节了?

NO,NONONO .重点3来了  ——> obj = (id)calloc(1, size);   6523行

这个 calloc 最终会走到这里(下图)

随便说说 alloc 和 init

calloc进行的内存对齐

随便说说 alloc 和 init

16倍数对齐

所以最终 zuyuClass 的这个对象内存中占用的空间是32字节而不是24字节

alloc我们就说到这里

接下来简单说说 init. 为什么要简单说说呢,因为没办法详细说啊

来,我们看一眼源码

随便说说 alloc 和 init

init源码

随便说说 alloc 和 init

rootinit

看到了吧 .init 干嘛了?init 啥都没干!只是返回了自己!

所以也就解释了一开始抛出的问题  .是不是看到这里已经颠覆了你的 alloc 是开辟空间,init 是初始化的理解?

可能有同学要问一下,init 既然啥都没干,为啥还要 init 这个方法,要它何用?

一句话回答, 自定义初始化. 也就是重写 init.  

那么现在最后抛出一个问题

在创建某一个类的对象的时候,alloc 和 init 分别起到了什么作用. 是不是瞬间感觉脑海里的回答比之前高大上了许多 

作者:_zuyu  作为一个开发者,有一个学习的氛围跟一个交流圈子特别重要这是一个我的iOS交流群:869685378,不管你是小白还是大牛欢迎入驻 ,分享BAT,阿里面试题、面试经验,讨论技术, 大家一起交流学习成长!

相关文章:

  • 2022-01-10
  • 2021-06-01
  • 2022-12-23
  • 2021-10-03
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2022-02-13
  • 2021-11-27
相关资源
相似解决方案