2015-10-20 90 views
3

我知道還有其他類似的問題,但沒有回答我的問題。'必需的'初始化'初始化(編碼器:)'必須由UIViewController的子類提供

所以我有一個ViewController與在XIB中定義的佈局。從另一個視圖控制器我想要做這樣的事情

let destVc = DestViewController(model:someModelData) 
self.showViewController(destVc,...) 

和DestViewController定義如下:

class DestViewController : UITableViewController { 
    var model: SomeModelData { 
     didSet { 
      self.tableView.reloadData() 
     } 
    } 

    init(model: SomeModelData) { 
     self.model = model 
     super.init(style: .Plain) 

    } 

    //...implementation below 
} 

我之所以想這樣做,這樣一來是因爲

1)我不希望不得不爲我的模型數據使用可選項或隱式展開的可選項,這種視圖控制器肯定需要,實際上這個模型數據構成其合同的一部分

2)這使我想起了在初始化程序中使用模型的另一個好處,它爲任何想要創建這些ViewControllers之一的人定義了明確的契約,並由swift的強類型系統加強。

的問題是,這並不編譯,Xcode中說:

'required' initializer 'init(coder:)' must be provided by subclass of UIViewController 

這是真的,因爲在UIViewController中不申報的init(編碼器)作爲「必要」初始化器的文檔怪異,它是一個指定的初始化者是的,但沒有在swift manual的地方說我必須覆蓋指定的初始化者只需要的。

這是怎麼回事就在這裏,爲什麼我需要添加:

required init?(coder aDecoder: NSCoder) { 

} 

要使它發揮作用?

請注意,這裏是UITableViewController的swift文檔,當我點擊cmd時出現在xcode中。注意缺乏「必要」的的initWithCoder

public class UITableViewController : UIViewController, UITableViewDelegate, UIScrollViewDelegate, UITableViewDataSource { 

    public init(style: UITableViewStyle) 
    public init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) 
    public init?(coder aDecoder: NSCoder) 

    public var tableView: UITableView! 
    @available(iOS 3.2, *) 
    public var clearsSelectionOnViewWillAppear: Bool // defaults to YES. If YES, any selection is cleared in viewWillAppear: 

    @available(iOS 6.0, *) 
    public var refreshControl: UIRefreshControl? 
} 

回答

5

之前,如果你覆蓋類的「指定」初始化的,雖然你沒有繼承任何其他指定的初始化。但是因爲UIView採用NSCoding協議,所以需要一個init(編碼器:)初始值設定項。這就是爲什麼你需要實現init(coder:)

init(coder decoder: NSCoder) { 
    super.init(coder: decoder) 
} 
+0

NSCoding協議並沒有說需要這種初始化器,如果我的超提供它爲什麼我需要做的呢? –

+1

如果有一天有人將你的類子類化......並且如果使用init(編碼器)初始化該類實例,則編譯器將具有執行層次結構 –