malloc 初始化_你真的了解 NSObject 对象的初始化吗?

在上一篇文章《利用__attribute__特性提高 APP 的鲁棒性》中,提及了NS_DESIGNATED_INITIALIZER属性。该属性表示指定初始化方法,今天的主题就是聊一聊NSObject的初始化流程。

初始化分为两步:

1. 分配内存

2. 初始化对象的成员变量

93538d22ff9ab7970b56494a256e35d0.png

分配内存

如果有C语言开发经验的人,malloc之后,一般需要memset一下。但在Objective-C里面,可不是这样的。

b661fb71e4008551aeba5a47e9eb4a36.png

苹果这段话表达了三个意思:

1. 开辟一个内存空间

2. isa变量和引用计数

3. 将所有的变量初始值置为0

初始化

从上面的描述中,仅仅alloc出来的对象还不能直接使用,还需要调用初始化函数。

以下是NSObject的初始化函数声明:

020c15ae372d3a743adcf0e10d90f6bc.png

而这里的init函数是NS_DESIGNATED_INITIALIZER的,也就是指定了初始化函数。

与指定初始化函数(designated initializer)对应的是便利初始化函数(convenience initializers)

接下来分析一个具体的例子:

#import <Foundation/Foundation.h>

这里声明了一个指定初始化函数initWithCount和一个便利初始化函数:initWithCount:year。

43882aedddcfb7e7e8b0e93476140e67.png

这里给出了三个警告,第一个警告表示父类的指定初始化函数没有找到。第二个和第三个警告表示不能直接调用父类的初始化函数

解决方案如下:

5542a96766dc3360ed2361351d3b7feb.png

从以上实现可以得出如下结论:

1. 如果子类有指定初始化函数,那么一定要实现所有父类的指定初始化函数,实现后的函数需调用本类的指定初始化函数

规则解读:P2PBomb需要实现父类的init函数,而且这里面必要还要调用[self initWithCount:0]

2. 如果子类有指定初始化函数,那么便利初始化函数必须调用自己的其它初始化函数(指定初始化函数或者其他便利初始化函数),不能调用super的初始化函数。

规则解读:在便利初始化函数中调用[self initWithCount:0],如果在这里调用[super init]会存在告警

3. 如果子类有指定初始化函数,子类指定初始化函数必须调用父类的指定初始化函数

规则解读:在指定初始化函数中,调用了[super init].

从以上规则,不难推导出另外一条规则,就是最终都要调用指定初始化函数。

再从苹果官方提供的图来理解一下这几条规则:

1dd00fa1c920fa8d65d8500325a0f61b.png

使用场景

也许会有人说,这个东西在实际代码中能用到吗?貌试没有用呢。OK,那我们举一个使用场景:

使用场景:定义NS_DESIGNATED_INITIALIZER,大多是不想让调用者调用父类的初始化函数,只希望通过该类指定的初始化进行初始化。

改进优化

如果父类的指定初始化函数比较多,一一实现一把比较繁琐,这时NS_UNAVAILABLE可以派上用场了。

#import <Foundation/Foundation.h>

如果调用者使用init 初始化,编译器就会给出一个编译错误。

使用NS_UNAVAILABLE后,就不需要在.m中重写父类初始化函数了。如果要允许调用者使用init就需要在.m中重写父类的初始化函数,如最开始提到的,否则就会报警告。注意,如果使用new来创建对象的话,即使init被声明为NS_UNAVAILABLE,编译器不会提示告警和错误。

限制:

NS_DESIGNATED_INITIALIZER不能出现在Category中。

参考文献:

Object Allocation

Adopting Modern Objective-C

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值