2017-04-22 32 views
2

我有一個對象稱爲導航器,我在init中設置。我打破它,確保它被設置。然而,當一個IBAction函數,linkBut​​tonClicked,get的調用,並嘗試使用導航器,我得到一個零例外。爲什麼?對象是零,雖然它是在初始化設置

class HomeCollectionViewCell: UICollectionViewCell { 
    let appDelegate:AppDelegate! 
    let navigator: Navigator! 
    @IBOutlet weak var linkButton: UIButton! 
    var destinationView:String? 
    var parentViewController:UIViewController? 

    @IBAction func linkButtonClicked(_ sender: Any) { 
     do { 
      try self.navigator.navigate(to: self.destinationView!, from: parentViewController!) 
     } catch { 

     } 
    } 

    required init?(coder aDecoder: NSCoder) { 
     self.appDelegate = UIApplication.shared.delegate as! AppDelegate 
     self.navigator = self.appDelegate.navigator 

     super.init(coder: aDecoder) 
    } 

    override func prepareForReuse() { 
     super.prepareForReuse() 

     // do resetting here if needed, like empty out data 
     linkButton.setTitle(nil, for: .normal) 
    } 
} 
+0

前兩個屬性不應該是IUO,如果它們不是,編譯器會通過指出它們沒有被正確初始化來幫助你解決這個問題。 –

回答

1

當您檢索從某種編碼的商店如核心數據對象的init?(coder: NSCoder)初始化器得到使用。該初始化程序是NSCoding協議所要求的,並且僅用於以反序列化對象。因此,不會在創建對象時調用。只有在您使用NSCoding序列化對象並稍後將其反序列化時纔會調用它。

你想,以確保一定的價值將在您的視圖設置覆蓋功能是init(如果你真的想使用它的init,重載的方法是init(frame:))。相反,您應該在視圖控制器的viewDidLoad方法中設置要使用的變量。

+0

明智的解釋。非常感激!還有一個問題。正如我所說當這個控制器加載所需的init被調用時,儘管我沒有使用任何類型的存儲或顯式序列化。這是從哪裏來的,爲什麼我的代碼不能使用它? –

+0

我實際上並不確定它爲什麼會被調用。我懷疑這可能與Swift如何在內部處理對象初始化有關,但我真的不知道確切的原因。 –

+0

'init(coder:)'是從nib創建對象時使用的初始化程序。 –