OC源码探索02:alloc、init和new的区别
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OC源码探索02:alloc、init和new的区别相关的知识,希望对你有一定的参考价值。
参考技术A 在 callAlloc 方法中我们通过断点调试发现,是执行到 _objc_rootAllocWithZone其中 cls->ISA()->hasCustomAWZ() 表示 判断一个类是否有自定义的+allocWithZone 实现
obj = (id)calloc(1, size) 通过 instanceSize 计算的内存大小,向内存中申请 大小 为 size的内存,并赋值给obj,因此 obj是指向内存地址的指针
这里我们可以通过断点调试的方式,来 po obj 观察 obj 的变化,未执行 calloc 前为 nil ,执行后为一个 16进制地址
这个过程主要是初始化一个isa指针,并将isa指针指向申请的内存地址,在将指针与cls类进行关联,同样也可以通过断点调试的方法,在执行完 initInstanceIsa 后,在通过 po obj 可以得出一个 对象指针 ,而不是先前的 16进制地址
这里的 init 是一个 构造方法 ,是通过 工厂设计 ,主要是用于给用户提供构造方法入口。这里能使用id强转的原因,主要还是因为 内存字节对齐 后,可以使用类型强转为你所需的类型
通过源码可以得知, new 函数中直接调用了 callAlloc 函数,且调用了 init 函数,所以可以得出 new 其实就等价于 [alloc init]
构造方法
对象的构造方法
创建一个对象, 我们直接通过new方法就可以创建一个OC实例对象。这个+new方法是继承NSObject获得的。其实创建对象+new方法分为两个过程的。
// 调用+aalloc分配存储空间 CHPerson *p = [CHPerson alloc]; // 调用-init初始化 p = [p init];
+alloc方法是分类内存空间,并将内存空间的地址返回,此时的对象内存空间是不可直接使用,需要调用-init进行初始化。
以上是关于OC源码探索02:alloc、init和new的区别的主要内容,如果未能解决你的问题,请参考以下文章