OC对象原理-alloc的探索

1. 用到的软硬件

  • Macbook Air
  • iPhone8手机一枚
  • macOS Mojave 10.14.6
  • Xcode 11.3.1
  • Object-C(编程语言)

2. 为什么实例化一个对象总要[[xxx alloc] init]

你会不会有这样的疑问,那我们一起先从alloc入手一步一步来探究,首先打开xcode->创建工程项目。如图


1.png
2.png
3.png

在我们下面代码处打上段点

ViewController *vc = [ViewController alloc];

然后点击运行,运行成功断点会卡在我们打断点的位置。如图

5.png

这里按住control这个时候横线会变成小圆点,然后在点击会发现我们跳入到了objc_alloc这个方法
4.png

由于这个方法是底层里面的方法,我们这里并不能获得,所以我们需要这个时候我们在这里打上一个符号断点(Symbolic Breakpoint),输入objc_alloc,会发现我们的alloc的实现方法来自于libobjc.A.dylib这个库里面(libobjc.A.dylib对应于官方给的objc4这个源码库里面)

12.png
13.png

3. 下载探究alloc的源码和实现

  • 源码下载地址 https://opensource.apple.com/tarballs/
  • objc4-781源码 https://pan.baidu.com/s/1h33XksmvMAvmojxgTWKi9Q 提取码: cfei
    打开我们下载好的objc4-781源码(这里已经经过一些配置,可以方便运行)
    14.png

这个时候我们在去按住cmd就可以跳到原生方法里面,看到它是如何实现的。


15.jpg

其他的都不重要,最后我们的alloc回调来自_class_createInstanceFromZone这个方法里面看看它是如何实现的。

16.png

通过测试下来,发现最主要三种方法来实现我们的alloc的操作
1、cls->instanceSize
2、calloc
3、obj->initInstanceIsa
那么这三种方法分别做了什么呢?

17.jpg

3. init和new做了什么?

查看我们的源代码可以找到init()的实现方法

- (id)init {
    return _objc_rootInit(self);
}
id
_objc_rootInit(id obj)
{
    return obj;
}

好尴尬,这个init什么事情都没有做,那么我们为什么总是会
LGPerson *objc = [[LGPerson alloc] init];岂不是只要
LGPerson *objc = [LGPerson alloc];
其实是可以的,但是有的人习惯在init里面重新写东西比如

-(id)init(){
  self.xx = xxxxx;
  self.xx = xxxxx;
  ...
}

所以建议你还是带上init

在看看new()的方法

+ (id)new {
    return [callAlloc(self, false/*checkNil*/) init];
}

可以出来,这个new相当于 alloc+init;

4. 总结

alloc用来开辟系统内存。init什么也没有干,new则是alloc+init。
这里有我写的一篇关于fastpath和slowpath片解

你可能感兴趣的:(OC对象原理-alloc的探索)