前言
我们都知道, 在oc中创建一个对象的实现是这样的:
NSObject *obj = [[NSObject alloc] init];
即两步创建, 从字面意思可以理解为: 分配内存 和 初始化
那么这个alloc
和 init
分别都做了什么事情呢?
正文
alloc
alloc
负责创建对象, 这个过程包括了分配足够的内存来保存对象
, 写入isa指针
, 初始化引用计数
, 以及重置所有实例变量
这四个过程.
在OC的源码头文件中可以看到, alloc的定义如下:
+ (instancetype)alloc OBJC_SWIFT_UNAVAILABLE("use object initializers instead");
即: alloc
方法会返回一个未被初始化的对象实例.
我们知道OC中的消息机制是这样的: 每一个方法都将转化成一条 objc_msgSend()
函数.
换言之, 也就是说alloc
方法提供了objc_msgSend()
函数的发送目标.
init
init
负责初始化对象, 这意味着此时此对象处于可用状态, 即对象的实例变量可以被赋予合理有效值.
在OC的头文件中可以看到, init的定义如下:
- (instancetype)init;
这个没什么要说的, 不过这个要提一下另一个问题:
我们在重写一个对象的init
方法的时候, 都是这样的格式:
- (instancetype)init {
if (self = [super init]) {
//TODO...
}
return self;
}
我们都只要, 重写的时候要调用 [super init]
, 那么到底为什么要这么写呢 ?
这里有一个很重要的部分:
init
方法可以通过返回nil
来告诉开发者, 初始化失败了
即, 如果你的超类初始化自己的时候失败了, 那么当前的类即处于一个不稳定状态,
即有可能你的初始化成功, 也有可能失败.
所以, 此时你的实现里不要再继续你的初始化并且要通过返回nil
如果不这么做的话, 接下来的操作可能会操控一个不可用对象(即创建失败),
这个行为是不可预测的, 有可能会导致程序崩溃.
所以我们在重写init
方法的时候, 要用以上的写法, 保证你的创建过程的容错性.`
结尾
谢谢.