自定義控件初始化中常見的幾種錯誤(指定構造器和便利構造器)
截圖:

意思是:
1.沒有添加重寫符
override(重寫父類方法)2.沒有重寫initWithCoder方法。(此方法只對應初始化是從xib,執(zhí)行代碼只的是,未從xib初始化)

意思是:為初始化父類的init方法

意思是:必須代理初始化自己的方法

意思是:不認識此類型的Default

意思是:禁止調用此初始化方法

意思是:屬性label沒有在父類初始化方法調用之前初始化
看到這里是不是有種崩潰的心情,別著急,對于OC和Swift的初始化,蘋果官方給了一些很合理的解釋,請點開這里:https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Initialization.html
定義Swift初始化方法,必須遵循三條規(guī)則:
1.指定構造器必須調用它直接父類的指定構造器方法
2.便利構造器必須調用同一類中定義的其他初始化方法
3.便利構造器在最后必須調用一個指定構造器。
圖形說明:

便利構造器 前面加
convenience 指定構造器什么都不用加,系統初始化方法 要加override

還需要注意的是:
和OC一樣,未初始化時,屬性是不被賦值的,因為其內存空間不存在

從這里我們來看Swift是怎么進行初始化的:
1.第一階段,是實例的所有屬性被初始化
2.第二階段,實例的所有屬性可以再次的調整以備之后的使用
Swift的編譯器會對初始化的方法進行安全地檢查已保證實例的初始化可以被安全正確的執(zhí)行:
1.指定構造器必須要確保所有被類中提到的屬性在向上調用父類的指定構造器前被初始化,之后才能將其他構造任務移交給父類的中的構造器。
2.指定構造器必須先向上調用父類中的構造器,然后才能為任意屬性賦值
3.遍歷構造器必須線調用同一個類中的其他構造器,然后再為屬性賦值
4.構造器在第一個階段構造完成之前,不能調用其他任何實例方法,不能讀取實例屬性的值,self不能被引用
在這里解釋初始化所謂的第一階段:
初始化的第一個階段:
1.某個指定構造器或便利構造器被調用
2.完成新的實例內存的分配,但此時內存還沒有被初始化
3.指定構造器確保其所在類引入的所有存儲型屬性都已賦值。存儲型屬性所屬的內存完成初始化。
4.指定構造器將調用父類的構造器,完成父類屬性的初始化
5.這個調用父類構造器的過程沿著構造器鏈條一直往上執(zhí)行,直到到達構造器料條的最頂部(重復1—4步驟)
6.當到達了構造器鏈條的最頂部,且已確保所有實例包含的存儲型屬性都已經賦值。這個實例的內存才會被認為已經完全初始化了

注意:
1。子類的便利構造器首先會被調用,此時便利構造器還不能修改子類的任何屬性。
2.便利構造器會調用子類中的指定構造器,指定構造器(子類)要確保所有的屬性都已賦值,完成所屬內存的初始化
3.接著會指定構造器(子類)會調用父類中的指定構造器,完成父類屬性所屬內存的初始化,直到達到構造器鏈條的最頂部,所有的屬性以及內存被完全初始化,然后進入第二階段

便利構造器內存未被初始化,不能修改屬性

第二階段:
1.從頂部構造器沿著鏈條一直向下,每個構造器鏈條中類的指定構造器都有機會一步定制實例。構造器此時可以訪問self,修改它的屬性并調用實例方法等等
2.最終,任意構造器鏈條中的便利構造器可以有機會定制實例和使用self

創(chuàng)建的錯誤注意點:
1.如果子類沒有定義任何指定構造器,那么會默認繼承所有來自父類的指定構造器

2.指定構造器必須調用它最近父類的指定構造器‘

3.便利構造器必須調用同一個類中定義的其他構造器(指定或便利都可以)

4.如果子類未定義任何指定構造器,那么會默認繼承所有來自父類的指定構造器
5.指定構造器必須要確保所有被類中提到的屬性在代理向上調用父類的指定構造器前被初始化,之后才能將其他構造任務交給父類的構造器

