举例:
Person *p = [Person alloc];
Person *p1 = [p init];
Person *p2 = [p init];
运行得出结论
alloc:消息发送 objc_msg_send(id self,sel alloc),创建对象且分配内存地址,而 init :创建指针地址指向已创建好的内存地址。p、p1、p2 的对象地址是同一个,但是指针地址却不同,即增加了引用计数,同时有 3 个指针指向这块内存地址。
源码探索
通过 alloc 设置符号断点进行探索 也可以下载 objc 源码探索:
-> alloc
-> _objc_alloc
-> callAlloc
-> _objc_rootAllocWithZone
-> _class_createInstanceFromZone【计算内存大小,申请内存空间,降对象指针和内存地址绑定】
-> objc_msg_send
64 位处理器,开辟内存最少 16字节 不足16字节 设置 16字节,保证开辟的内存地址大小永远都是 16 字节的倍数 即内存对齐,提高 cpu 的读取效率。
其中 Person 有两个字符串属性每一个int 属性 那么 对象 p 开辟的内存大小为 8+8+8+4 = 28 ->内存对齐:32字节
一个指针 8字节,字符串 8字节,int 类型 4个字节
NSObject 走一遍 callAlloc,而 自定义类 走 两遍 callAlloc
因为 NSObject 是系统类 在编译的时候,他的 isa 指针已经存在了,而自定义类 只有 alloc 时 才会调用 initialize 进行初始化,所以会走第二遍。
总结
alloc:创建对象且分配内存地址,而 init :创建指针地址指向已创建好的内存地址