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


156

私は残りのプロジェクトをSwiftで継続することにしました。カスタムクラス(のサブクラス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.
    }
    */
}

何か提案してください

回答:


207

問題

これはinit?(coder aDecoder: NSCoder)、ターゲットに初期化子がないために発生しUIViewControllerます。UIViewControllerからUIStoryboard呼び出しをインスタンス化するため、このメソッドが必要です。

我々は初期化する方法を確認するにはUIViewControllerからUIStoryboard、見てくださいここに

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

そのためのObjective-Cは、自動的にすべての必要な継承するUIViewControllerイニシャライザ。

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

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


解決

1.最初の方法

init?(coder aDecoder: NSCoder)ターゲットに手動で実装するUIViewController

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

2. 2番目の方法

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



4
これをありがとう。簡単なフォローアップ... TableViewControllerファイルを作成するとき、Xcodeにはすでに2つの init関数init(style: UITableViewStyle) { super.init(style: style) // Custom initialization } があるのはなぜですか?そして、なぜAppleがデフォルトで2番目のinitを含まないのか?
Trevor McKendrick 14

これは、iOS 7またはiOS 8とは関係ありません。これは、Swiftが初期化子を継承する方法に関連しています!
スルタン2014年

public init(view:UIViewController、frame:CGRect){self.viewController = view self.imageName = "" self.actionName = "" super.init(frame:frame)}
scrainie

最初の方法はうまくいきました!私の動的テーブルは最終的に動的セルでいっぱいになりました!!! ラインfatalError( "init(coder:) has not been implemented")がアプリを停止させたからです。
ホセマヌエルアバルカロドリゲス2016

25

@ 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 Session 403 "Intermediate Swift"を参照してください。


セッション403の説明を指摘していただきありがとうございます。ただし、子クラスに便利な初期化子しかない場合は、スーパークラスの初期化子を継承しますか。
jamiltz 2014年

1
はい。独自の指定されたinitメソッド(スーパーinitを呼び出すもの)を提供する場合にのみ、スーパークラスinitメソッドが継承されないようにします。次に、クラスに追加してスーパーバージョンを呼び出すだけで、サポートするスーパーinitを指定する必要があります(@ 3r1dの回答のように)
Dave Wood

子クラスに(指定された)init()なしで便利なinit()のみを含めると、コンパイルエラーが発生します。これは、便利なinit()関数が関数定義内でself.init()を呼び出す必要があるためです。
2016年

@narumolPug不正解です。指定されたinitメソッドを含める必要はありません。子クラスは、それらをスーパークラスから継承します。self.init()スーパーバージョンを実行するを引き続き呼び出すことができます。
Dave Wood

ビデオの正確な瞬間はこちらyoutu.be/W1s9ZjDkSN0?t=2030
Honey

10

swift UICollectionViewCellsで同じ問題が発生する場合は、@ 3r1dが提案したコードUICollectionViewCellを、ビューコントローラーではなくカスタムクラスに追加します。

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

どのUICollectionViewCellを参照していますか?コーダーでの初期化は、viewControllerを初期化する方法です
E-Riddie

この例ではありませんが、誰かが問題を抱えている場合(私はそうしました)... UICollectionViewControllerを使用しようとする場合、カスタムセルの.swiftファイルで、コーダーで初期化する必要があります。
Nick Yap 14

2
あなたはインスタンス化するこの方法を使用このコードを毎回追加する必要がありstackoverflow.com/questions/24035984/...を
E-Riddie

3

Swiftのコードが必要な場合:

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

[編集]これは古いバージョンのSwift用でした。おそらくもう機能しません。


3

プログラムによる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

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


プロパティをを介してオプションとして宣言することもできます?
ジュリアンB.
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.