2016-07-15 120 views
38

我是從網上課程學習iOS開發,每次我做一個自定義視圖(自定義表視圖細胞,採集觀察室等)的教練始終貫徹這個初始化:init編碼器aDecoder究竟是什麼?

required init?(coder aDecoder: NSCoder) { 
     super.init(coder: aDecoder) 

    } 

到底爲什麼總是我必須調用這個?它有什麼作用?我可以將屬性放入init嗎?

+2

這個答案會幫助你http://stackoverflow.com/questions/24036393/fatal-error-use-of-unimplemented-initializer-initcoder-for-class謝謝 –

+0

如果你實現了一個實現了'NSCoding'的對象,那麼你需要實現這個初始化器,因爲它需要實現'NSCoding'的類。您至少必須調用超類init方法。如果'NSCoder'包含你的類的編碼屬性,那麼你可以使用這種方法來恢復那些 – Paulw11

+1

嘗試搜索。這個問題在這裏已經被回答了很多次。 – matt

回答

7

實現一個初始化的要求是兩件事情的結果:

  1. Liskov substitution principle。如果S是T的一個子類(例如,MyViewControllerViewController的子類),則S對象(MyViewController的實例)必須能夠替換T對象(實例爲ViewController)的位置。

  2. 如果在子類中明確定義了任何初始值設定項,則在Swift中不會繼承初始值設定項。如果明確提供了一個初始化程序,則必須明確提供所有其他初始化程序(然後纔可以撥打super.init(...))。基本原理見this question。它在Java中,但仍然適用。

到1點,一切原來ViewController可以做什麼,MyViewController子類應該是能夠做到的。一個這樣的事情是能夠從給定的NSCoder初始化。到了第2點,你的MyViewController子類不會自動繼承這個能力。因此,您必須手動提供符合此要求的初始化程序。在這種情況下,你只需要將它委託給超類,讓它做它通常會做的事情。

+0

構造函數不被繼承是非常有意義的:如果使用基類的(繼承)初始化方法初始化派生類的實例,那麼派生類新定義(「添加」)的非繼承屬性將會永遠不會被初始化。 –

+0

實際上,初始值設定項是在Swift中繼承的,因爲您沒有在您的子類中提供任何自己的初始值設定項實現。如果新定義的非繼承屬性具有默認值,那麼可以避免在子類中編寫任何初始化器,並簡單地繼承所有超類的初始化器。見[這裏](https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Initialization.html#//apple_ref/doc/uid/TP40014097-CH18-ID222) – TheBaj

+0

@TheBaj好點,我忽略了這一點。 – Alexander

45

我會從相反的方向開始回答:如果要將視圖的狀態保存到磁盤,該怎麼辦?這被稱爲系列化。反過來是反序列化 - 從磁盤恢復對象的狀態。

NSCoding協議定義了2種方法進行序列化和反序列化對象:

encodeWithCoder(_ aCoder: NSCoder) { 
    // Serialize your object here 
} 

init(coder aDecoder: NSCoder) { 
    // Deserialize your object here 
} 

那麼,爲什麼需要它在你的自定義類?答案是Interface Builder。將對象拖放到故事板並對其進行配置時,Interface Builder會將該對象的狀態序列化到磁盤上,然後在故事板出現在屏幕上時將其反序列化。您需要告訴Interface Builder如何執行這些操作。至少,如果您沒有爲您的子類添加任何新屬性,則可以直接要求超類爲您進行打包和解包,因此請致電super.init(coder: aDecoder)。如果你的子類更復雜,你需要爲子類添加你自己的序列化和反序列化代碼。

這與Visual Studio的方法形成鮮明對比,該方法將代碼寫入隱藏文件以在運行時創建對象。

+0

爲什麼不把所有內容都放在awakeFromNib中,忘記使用'init(coder aCoder:NSCoder)'? – Honey

+0

@霍尼 - 總而言之,「有時你不能那樣做」。你通常可以但不總是。 – Fattie

+0

@Fattie是不是太複雜或不必知道的細節?如果你不介意解釋? – Honey