0x01 分配对象
分配(allocation)是一个新对象诞生的过程。
向某个类发送alloc消息,就能为类分配一块足够大的内存,用来存放该类的全部实例变量,并返回对象的指针。
同时alloc方法还顺便将这块内存区域全部初始化为0:
- 整形初始化为0;
- 浮点型初始化为0.0;
- 字符型初始化为'\0';
- 布尔型初始化为null;
- 指针初始化为nil。
0x02 初始化对象
与分配对应的操作是初始化。
初始化从操作系统中获得一块内存用于存储对象。
init方法(初始化对象所使用的方法)一般都会返回其负责初始化的对象。
0x03 创建对象的方法
在Objective-C中有两种等价的创建对象方式:
- 类名 *对象名 = [[类名 alloc] init];
- 类名 *对象名 = [类名 new];
按照Cocoa的惯例,一般是使用alloc+init而不使用new。
因为根据Apple的官方文档,new方法是NSObject对象的一个静态方法,new实际上就是alloc和init方法的组合。
但Apple还是推荐我们使用第一种方法,首先是明确分开了分配与初始化两个概念,再者将init独立开来,我们就可以使用自己定义的init方法来做一些非默认的初始化。
当然,如果子类没有提供init方法,自然调用的就是父类的init方法了。
从安全性的角度来收,我们使用对象之前是一定要对对象进行初始化的,因此在定义类的时候一定要提供初始化方法。
但不一定要用init作为方法名。
使用init作为方法名只是重写了NSObject的init方法而已,如果自己重新定义一个初始化方法也是允许的,只要在使用的时候记得调用自定义的初始化方法就好。
0x04 编写初始化方法
(id) init {
if (self = [super init])
{
engine = [Engine new];
tires[0] = [Tire new];
tires[1] = [Tire new];
tires[2] = [Tire new];
tires[3] = [Tire new];
}
return (self);
} // init
这里终于可以详细讲下if (self = [super init])的作用:
首先,我们知道对象继承的概念,一个子类从父类继承,那么也要实现父类的所有功能,这就是is-a的关系,比如说狗是哺乳动物,那么狗必定具有哺乳动物的特征和功能。所以在子类的初始化方法中,必须首先调用父类的初始化方法,以实现父类相关资源的初始化。例如我们在初始化狗这一对象时,必须先初始化哺乳动物这一对象,并把结果赋予狗,以使狗满足属于哺乳动物这一特征。
典型的,在iOS下,所有的类都继承于NSObject,而NSObject的init方法很简单,就是return (self)。当父类的初始化完成之后,即self不为nil的情况下,就可以开始做子类的初始化了。
这段代码中最先运行的是[super init],其作用是让父类完成其自身的初始化工作。
对于继承了NSObject的类来说,调用父类的init方法可以放NSObject执行它所需的所有操作,以便对象能够响应消息并处理引用计数器。
而对于从其他类继承的类,通过这种方法可以实现自身的全新初始化。
如果在初始化一个对象时出现问题,则init方法可能返回nil值,此时if (self = [super init])的判断结果就不会让主体代码运行。