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];
然后点击运行,运行成功断点会卡在我们打断点的位置。如图
这里按住control这个时候横线会变成小圆点,然后在点击会发现我们跳入到了
objc_alloc
这个方法4.png
由于这个方法是底层里面的方法,我们这里并不能获得,所以我们需要这个时候我们在这里打上一个符号断点(Symbolic Breakpoint),输入objc_alloc,会发现我们的alloc的实现方法来自于libobjc.A.dylib
这个库里面(libobjc.A.dylib对应于官方给的objc4这个源码库里面)
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
这个方法里面看看它是如何实现的。
通过测试下来,发现最主要三种方法来实现我们的alloc的操作
1、cls->instanceSize
2、calloc
3、obj->initInstanceIsa
那么这三种方法分别做了什么呢?
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片解
网友评论