------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------
构造方法(init方法)在OC中是使用非常频繁的方法,构造方法的本意就是对对象进行构造(对对象的实例变量进行初始化),因为是对对象的实例变量进行初始化,所以是并且只能是对象方法,以‘-’开头。
构造方法的举例如下
例
Dog *d = [[Dog alloc]init];
其中alloc表示分配控件,init 即为构造方法表示初始化,init继承自NSObject。
由于这是系统自动进行的初始化,所以初始化的值往往不是我们想要的(对象类型:系统自动初始化为nil,基本类型:系统自动初始化为 0),所以在实际应用中我们常常重写或者自定义构造方法,重写构造方法的官方文档推荐写法为:
- (id)init {
self = [super init];
if (self) {
//Initialize self.
}
return self;
}</span>
[super init]的作用:
面向对象的体现,先利用父类的init方法为子类实例的父类部分进行属性初始化,初始化完成之后反回当前对象的指针。因为不管是什么类,其基类(或者称根源类)一定是NSObject,所以要像获得基类的属性方法就一定要用 super 来获得父类(实际使用中的类未必直接继承至NSObject,可能是其父类甚至爷爷类继承至NSObject)的init方法。
if语句的作用
调用[super init]时可能会alloc失败,所以我们通过判断self ! =nil 来决定是否执行下面的初始化操作,如果为nil 实例创建失败,终止if内的语句执行。
例:Person类的init方法重写
- (instancetype)init{
self = [super init];
if (self) {
//此处写子类初始化的内容
_age = 10;
}
上方代码即为,我每创建一个该类的对象,它的age属性就默认为10
如果我们有一个继承Person 的子类Student,并且Student有另外一个属性stuNum,我们想给stuNum自动初始化另外一个值怎么办呢?
例
-(instancetype)init{
self = [super init];//调用父类Person的init方法,会先把继承的age属性初始化为10
if(self){
_stuNum = 1;
} return self;
}
看到这里应该会有人奇怪,为什么官方推荐的是-(id)开头,而我的例子却全是-(instancetype)开头呢,这里就涉及到id和instancetype的差异了,简单的说,id是旧时代的东西,instancetype是新时代的东西,他们都可以返回一个对象类型,在此处的区别在于id返回的是未知的对象类型,instancetype返回的是所在类的对象类型,高下立判,所以在此处请尽量使用instancetype类型。
虽然重写构造方法可以达到一定意义上的按我们所构想的那样去初始化值,但仍不够完美,实际情况中我们经常遇到用接收的值去进行初始化,这就要进行构造方法的自定义了。
构造方法的自定义严格来说就是一个新的对象方法,只不过我们给了它初始化实例变量的功能。
注意:即便我们自定义了构造方法,原构造方法init仍然存在,我们仍可调用它。
自定义构造方法与重写构造方法的不同在于方法名和参数的不同,其他必须严格相同,自定义构造方法命名一般为“initWith***”
例
- (instancetype)initWithDict:(NSDictionary *)dict{
if (self = [super init]) { //注:此处将 self=[super inti]; 与if内的判断写在了一起
self.name = dict[@"name"];
self.icon = dict[@"icon"];
}
return self;
}
该方法为一个自定义的构造方法,功能是将字典内的数据转为模型(即将字典的数据用类的对象来存储,更方便于操作和拓展)。