構(gòu)造方法
1.什么是構(gòu)造方法?
初始化對(duì)象的方法.
默認(rèn)情況下,在 OC 當(dāng)中創(chuàng)建1個(gè)對(duì)象分為兩部分(new 做的事):
+alloc:分配內(nèi)存空間
-init :初始化對(duì)象
2.構(gòu)造方法的作用是?
用作初始化對(duì)象的成員變量.
把 C 語言指針初始化為 NULL
把 OC 對(duì)象初始化為 nil
把基本數(shù)據(jù)類型初始化為0
3.構(gòu)造方法的書寫格式是?
- (instancetype)init
{
self = [super init];
if (self) {
<#statements#>
}
return self;
}
構(gòu)造方法的結(jié)構(gòu)很重要.
第一步,調(diào)用指定的父類初始化函數(shù).該初始化函數(shù)返回父類對(duì)象的一個(gè)經(jīng)過初始化的實(shí)例.
第二步,把返回回來的實(shí)例必須將其賦值給特殊的變量 self.
第三步,如果在初始化過程中出現(xiàn)任何問題,初始化函數(shù)的協(xié)議指定返回一個(gè) nil對(duì)象,而不是一個(gè)有效的初始化對(duì)象.因此,在將父類的初始化函數(shù)返回值賦值 self 后,必須檢查 self 是否是 nil. 如果是,就不想要初始化自身的變量了,返回 nil 即可.上面的事例中,我們?cè)?if 語句中將變量賦值給 self 并檢查它是否是 nil.
第四步:構(gòu)造方法的真正目的除了創(chuàng)建 self 外,還用于初始化對(duì)象中的所有數(shù)據(jù)成員.因此在驗(yàn)證 self 不是 nil 后,就可以初始化變量了.在初始化變量后,就可以從初始化方法中返回 self.
疑問:在學(xué)習(xí)和使用構(gòu)造方法時(shí),我一直心里有個(gè)疑問:為什么 self = [super init];蘋果官網(wǎng)對(duì)此沒有明確的說明,所有的一切都是開發(fā)者的猜測(cè).
下面是我對(duì)此經(jīng)過多次測(cè)試,所得到結(jié)果的猜測(cè):
1.第一點(diǎn),[super init],之所以調(diào)用父類的 init 方法,是因?yàn)槿绻宇愔貙懥硕x在父類當(dāng)中的方法,在子類執(zhí)行過程當(dāng)中,就不會(huì)執(zhí)行父類當(dāng)中的該方法.而面向?qū)ο缶幊痰淖钪饕攸c(diǎn)之一就是:誰的事情,誰去做.子類當(dāng)中,繼承了父類的所有可繼承的成員變量,那么該些成員變量就應(yīng)該是父類自己去初始化,而不應(yīng)該子類替代父類去做初始化操作.所以此處需要調(diào)用父類的構(gòu)造方法.
2.第二點(diǎn),也就是難點(diǎn),為什么要將父類初始化后的實(shí)例對(duì)象賦值給子類當(dāng)中的 self ???這才是我疑惑非常久的問題.
猜測(cè)1.調(diào)用父類的初始化方法,肯定要返回一個(gè)對(duì)象,那么這個(gè)對(duì)象用誰去接收?應(yīng)該看 super 當(dāng)前代表的是誰,是什么類型來確定.
猜測(cè)2.如果父類初始化失敗,在子類當(dāng)中沒有值接收,就沒有辦法進(jìn)行把控,所以要賦值給一個(gè)當(dāng)前對(duì)象.
// 作用:初始化成員變量
-(instancetype)init
{
// 1.調(diào)用父類的初始化方法,進(jìn)行初始化子類繼承自父類的成員變量.
self = [super init];
// 問題:這里要返回一個(gè)初始化好的實(shí)例對(duì)象,那么用什么來接受這個(gè)對(duì)象???
// 1.1.用父類?
// 1.2.用子類本身?
// 結(jié)論:NSLog(@"super-%@",super.class);super 是本類對(duì)象,所以用 self 接受
// 3.因?yàn)檎{(diào)用父類初始化方法,可能初始化成功,可能初始化失敗,那么如果初始化失敗,就不應(yīng)該繼續(xù)下面的操作
if (self) {
// 3.1.如果父類初始化成功,下面開始初始化子類成員
_name = @"碼奴!";
}
// 4.返回已經(jīng)初始化好的對(duì)象
return self;
}