OC底层原理-alloc流程

2021-06-07  本文已影响0人  麟枫_Jack

在OC中我们经常考到alloc, 那alloc究竟为我们做了什么?

1.initInstanceIsa 计算申请的内存大小

我们可以通过调试得知申请的地址都是8的倍数,字节对齐的单元是8,至于为什么要字节对齐,是为了降低cpu的读取性能损耗和访问的安全性。

2.calloc 申请内存地址指针

3.initInstanceIsa 将申请的内存地址指针和isa指针即我们的类绑定起来

init 和 new

在源码中init做的事情是return _objc_rootInit(self),init把我们alloc 申请的类的指针给了对象,并且返回对象自己。init构造方法,并且可以重写。new做的事情是return [callAlloc(self, false/*checkNil*/) init],new就相当于 alloc+init,但是new不能像init一样进行重写。

下面是OC对象alloc的流程图 

对象的内存大小是以8字节对齐来计算的,而且由于父类有isa指针 ,就算我们的类对象中什么都没有,最少也会返回8,然后8<16,类对象的内存大小最小就是16字节。

问题一:有人说那给个8字节也够了,为啥要扩充到16字节呢?

如果是8字节对齐的话, 对象之间 isa 都是紧邻的, 没有一点空隙, 如果内存访问出现了一点错误或者偏移, 就会访问到其他对象, 就会出现一些野指针,内存访问错误之类, 发生了混乱, 所以为了使得对象之间的访问更加的安全, 就需要给对象之前预留一部分的空间, 预留多少合适呢, 毫无疑问, 当然是8字节, 为什么不是1,2,4字节呢? 一方面16字节是可以占用最小空间的合理内存空间, 即8的倍数, 另一方面也更加的安全, 各个对象的内存都是16字节, 偏移和访问时, 可以很好地进行对齐. 

问题二:为什么以8字节对齐,而不是16或者32

CUP每次读取都是固定8字节读取,以空间换取时间。但是有时候好几个char 1字节,没必要每个char补齐8字节,可以拼凑在一起。 

文章如有不当之处,欢迎大家指出。本人尚在初学阶段,还请大家多多指教。

上一篇下一篇

猜你喜欢

热点阅读