在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字节,可以拼凑在一起。
文章如有不当之处,欢迎大家指出。本人尚在初学阶段,还请大家多多指教。
网友评论