OC中[NSObject alloc] init]发生了什么

前言

我们都知道, 在oc中创建一个对象的实现是这样的:

NSObject *obj = [[NSObject alloc] init];

即两步创建, 从字面意思可以理解为: 分配内存 和 初始化
那么这个allocinit分别都做了什么事情呢?

正文

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方法的时候, 要用以上的写法, 保证你的创建过程的容错性.`

结尾

谢谢.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容