2017-04-22 12 views
2

私は、init内で設定したnavigatorというオブジェクトを持っています。私はそれが設定されていることを確認するためにそれを破る。しかし、IBAction func、linkBut​​tonClicked、getの呼び出し時にnavigatorを使用しようとすると、例外が発生します。どうして?オブジェクトはinitで設定されていてもnilです

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

最初の2つのプロパティはIUOであってはならず、そうでない場合、コンパイラは適切に初期化されていないことを示すことでこれを解決するのに役立ちます。 –

答えて

1

あなたは、このようなコアデータとしてエンコードされた店舗のいくつかの種類からオブジェクトを取得しているときinit?(coder: NSCoder)初期化子が使用されます。この初期化子は、NSCodingプロトコルで必要とされ、のみを使用してオブジェクトを逆シリアル化します。したがって、はオブジェクト作成時にが呼び出されません。 NSCodingを使用してオブジェクトをシリアル化し、後でそれを逆シリアル化する場合にのみ呼び出されます。あなたには、いくつかの値は、あなたのビューに設定されます確実にするために上書きしたい

機能がないそのinitである(そして、あなたは本当に、そのinitを使用したい場合は、オーバーロードする方法がinit(frame:)です)。代わりに、ビューコントローラのviewDidLoadメソッドで使用する変数を設定する必要があります。

+0

華麗な説明。とても有難い!もう1つの質問。このコントローラーがロードされるときに、必要なinitが呼び出されたと言いましたが、ストアや明示的なシリアル化を使用していません。これはどこから来て、なぜ私のコードでそれを利用できないのですか? –

+0

私は実際になぜ呼び出されているのかは分かりません。これはSwiftがオブジェクトの初期化を内部的に処理する方法と関係している可能性がありますが、実際の理由はわかりません。 –

+0

'init(coder:)'は、オブジェクトがペン先から作成されたときに使用される初期化子です。 –

関連する問題