构造方法
1.什么是构造方法?
初始化对象的方法.
默认情况下,在 OC 当中创建1个对象分为两部分(new 做的事):
+alloc:分配内存空间
-init :初始化对象
2.构造方法的作用是?
用作初始化对象的成员变量.
把 C 语言指针初始化为 NULL
把 OC 对象初始化为 nil
把基本数据类型初始化为0
3.构造方法的书写格式是?
- (instancetype)init
{
self = [super init];
if (self) {
<#statements#>
}
return self;
}
构造方法的结构很重要.
第一步,调用指定的父类初始化函数.该初始化函数返回父类对象的一个经过初始化的实例.
第二步,把返回回来的实例必须将其赋值给特殊的变量 self.
第三步,如果在初始化过程中出现任何问题,初始化函数的协议指定返回一个 nil对象,而不是一个有效的初始化对象.因此,在将父类的初始化函数返回值赋值 self 后,必须检查 self 是否是 nil. 如果是,就不想要初始化自身的变量了,返回 nil 即可.上面的事例中,我们在 if 语句中将变量赋值给 self 并检查它是否是 nil.
第四步:构造方法的真正目的除了创建 self 外,还用于初始化对象中的所有数据成员.因此在验证 self 不是 nil 后,就可以初始化变量了.在初始化变量后,就可以从初始化方法中返回 self.
疑问:在学习和使用构造方法时,我一直心里有个疑问:为什么 self = [super init];苹果官网对此没有明确的说明,所有的一切都是开发者的猜测.
下面是我对此经过多次测试,所得到结果的猜测:
1.第一点,[super init],之所以调用父类的 init 方法,是因为如果子类重写了定义在父类当中的方法,在子类执行过程当中,就不会执行父类当中的该方法.而面向对象编程的最主要特点之一就是:谁的事情,谁去做.子类当中,继承了父类的所有可继承的成员变量,那么该些成员变量就应该是父类自己去初始化,而不应该子类替代父类去做初始化操作.所以此处需要调用父类的构造方法.
2.第二点,也就是难点,为什么要将父类初始化后的实例对象赋值给子类当中的 self ???这才是我疑惑非常久的问题.
猜测1.调用父类的初始化方法,肯定要返回一个对象,那么这个对象用谁去接收?应该看 super 当前代表的是谁,是什么类型来确定.
猜测2.如果父类初始化失败,在子类当中没有值接收,就没有办法进行把控,所以要赋值给一个当前对象.
// 作用:初始化成员变量
-(instancetype)init
{
// 1.调用父类的初始化方法,进行初始化子类继承自父类的成员变量.
self = [super init];
// 问题:这里要返回一个初始化好的实例对象,那么用什么来接受这个对象???
// 1.1.用父类?
// 1.2.用子类本身?
// 结论:NSLog(@"super-%@",super.class);super 是本类对象,所以用 self 接受
// 3.因为调用父类初始化方法,可能初始化成功,可能初始化失败,那么如果初始化失败,就不应该继续下面的操作
if (self) {
// 3.1.如果父类初始化成功,下面开始初始化子类成员
_name = @"码奴!";
}
// 4.返回已经初始化好的对象
return self;
}
网友评论