web-dev-qa-db-ja.com

致命的なエラー:クラスに未実装の初期化子 'init(coder :)'を使用しています

私はSwiftで残りのプロジェクトを続けることにしました。ストーリーボードのView Controllerにカスタムクラス(UIViewcontrollerのサブクラス)を追加してプロジェクトをロードすると、次のエラーが表示されてアプリが突然クラッシュします。

致命的エラー:クラスに未実装の初期化子 'init(coder :)'を使用しました

これはコードです

import UIKit

class TestViewController: UIViewController {

    init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
        // Custom initialization
    }

    override func viewDidLoad() {
        super.viewDidLoad()
              // Do any additional setup after loading the view.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    /*
    // #pragma mark - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepareForSegue(segue: UIStoryboardSegue?, sender: AnyObject?) {
        // Get the new view controller using [segue destinationViewController].
        // Pass the selected object to the new view controller.
    }
    */
}

何か提案してください

151
Pratik Bhiyani

問題

これは、ターゲットUIViewControllerに初期化子init?(coder aDecoder: NSCoder)がないことが原因です。 UIViewControllerからUIStoryboardをインスタンス化すると呼び出されるので、このメソッドは必須です。

UIViewControllerからUIStoryboardをどのように初期化するかを見るためには、ここを見てください

これがObjective-Cの問題ではないのはなぜですか?

Objective-Cは、必要なすべてのUIViewController初期化子を自動的に継承するためです。

Swiftが初期化子を自動的に継承しないのはなぜですか?

Swiftはデフォルトでは安全のために初期化子を継承しません。しかし、すべてのプロパティが値(またはオプション)を持ち、サブクラスが指定された初期化子を定義していない場合、スーパークラスからすべての初期化子を継承します。


溶液

1.最初の方法

ターゲットUIViewControllerinit?(coder aDecoder: NSCoder)を手動で実装する

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

第二の方法

ターゲットUIViewControllerからinit(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?)を削除すると、スーパークラスから必要なすべての初期化子がDave Woodのように answer の下に継承されます。


201
E-Riddie

@ 3r1d以外の選択肢としては、代わりに次のinitメソッドをクラスから削除することです。

init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
    super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
    // Custom initialization
}

そのinitメソッドを含めることで、サブクラスがスーパークラスからinit(coder aDecoder: NSCoder!)を継承するのを防ぎます。含まないことで、あなたのクラスは両方を継承します。

注:詳細については、33:50マークのWWDC 2014セッション403「Intermediate Swift」を参照してください。

26
Dave Wood

Swift UICollectionViewCellsで同じ問題を抱えている人のために、@ 3r1dがView ControllerではなくあなたのカスタムUICollectionViewCellクラスに提案したコードを追加してください。

init(coder aDecoder: NSCoder!)
{
    super.init(coder: aDecoder)
}
9
Nick Yap

Swiftでコードが必要な人のために:

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

[編集]これはSwiftの古いバージョンのためのものです。おそらくもう動かないでしょう。

3
MXV

私はプログラム的なcollectionViewセルでこの問題を抱えていました、そしてopがvcについて尋ねていても私はまだ答えを探すときこの質問に着陸しました。私にとって問題は私が持っていたことでした

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

トップの答えがうまくいかなかったように実装されています。私がセルに持っていなかったのはイニシャライザでした:

// my programmatic cell was missing this
override init(frame: CGRect) {
    super.init(frame: frame)
}

それを追加したらエラーは消えました

1
Lance Samaria

内部メカニズムをうまく機能させるためのメソッドを追加するのではなく、属性を@lazyとして定義してクラススコープ内で初期化します。

0
hasancan85