init
alloc负责分配对象空间,init负责初始化对象。init是实例方法,返回的是初始化后的对象。
33.1编写init方法
BNRAppliance *a = [[BNRAppliance alloc] init];
如果BNRAppliance没有实现init方法,会执行NSObject定义的init方法。这样,所有的实例变量都会被初始化为0
33.2实现基本的init方法
某些情况下,实例变量初始化为0就能满足需要,但是,某些类的实例需要将实例变量初始化为非0的值。
- (instancetype) init{
self = [super init];
if(self){
_voltage = 120;
}
return self;
}
33.3instancetype类型
你编写的任何初始化返回方法都应该返回instancetype类型的值
33.4使用并检查父类的初始化方法
self = [super init];
将父类的init方法所返回的对象赋值给self
检查父类的初始化方法的返回值。确定不是nil并且有效。
少数类的初始化方法需要做一些特殊处理,下面举两个例子
1.出于优化考虑,init方法会释放已经分配了内存的对象,然后创建另一个新对象并返回
2.init方法在执行过程中发生了错误,所以会释放对象并且返回nil
33.5带实参的init方法
- (instancetype) initWithProductName:(NSString *)pn {
self = [super init];
if( self ){
_productName = [pn copy];
_voltage = 120;
}
return self;
}
- (instancetype ) init {
return [self initWithProductName:@"Unknow"];
}
33.6在init中使用存取方法
有的程序猿会使用存取方法
- (instancetype) initWithProductName:(NSString *)pn {
self = [super init];
if( self ){
[self setProductName:pn];
[self setVoltage:120];
}
return self;
}
这两种方法都适用。构建并运行程序
33.7多个初始化方法
应该遵循以下规则:
1.其他的初始化方法都应(直接的或间接的)调用指定初始化方法。
2.指定的初始化方法应该先调用父类的指定初始化方法,然后再对实例变量进行初始化
3.如果某个类的指定初始化方法和父类的不同(这里指的是方法名不同),就必须覆盖父类指定的初始化方法,并调用新的初始化方法
4.如果某个类有多个初始化方法,就应该在相应的头文件中明确的注明哪个方法是指定初始化方法
33.8禁用init方法
不了解你写的代码的其他程序猿,初始化时多半会用
BNRWallSafe *ws = [[BNRWallSafe alloc] init];
可以覆盖父类的指定初始化方法,告诉程序猿不能调用这个方法
- (instancetype)init {
[NSException rasie:@"BNRWallSafeInitialzation"
format:@"Use initWithSecretCode:,not init"];
}