web-dev-qa-db-ja.com

SwiftのUIViewControllerでデフォルトのsuper.init()を呼び出せないのはなぜですか?

ストーリーボードのUIViewControllerを使用していないので、オブジェクトのinitを渡すカスタムNSManagedObjectID関数が必要です。 Objective-Cのようにsuper.init()を呼び出したいだけです。このような:

init(objectId: NSManagedObjectID) {
    super.init()
}

しかし、次のコンパイラエラーが発生します。

スーパークラスUIViewControllerの指定された初期化子を呼び出す必要があります

これはもうできませんか?

67
SirRupertIII

UIViewControllerの指定初期化子はinitWithNibName:bundle:です。代わりに呼び出す必要があります。

http://www.bignerdranch.com/blog/real-iphone-crap-2-initwithnibnamebundle-is-the-designated-initializer-of-uiviewcontroller/ を参照してください

ペン先がない場合は、nibNameにnilを渡します(バンドルもオプションです)。次に、loadViewでカスタムビューを作成するか、viewDidLoadself.viewにサブビューを追加して、以前と同じように作成します。

100
occulus

別の素晴らしい解決策は、次のようにconvenience初期化子として新しい初期化子を宣言することです。

convenience init( objectId : NSManagedObjectID ) {
    self.init()

    // ... store or user your objectId
}

サブクラスで指定された初期化子をまったく宣言しない場合、それらは自動的に継承され、便利な初期化子内でself.init()を使用できます。

UIViewControllerの場合、デフォルトのinitメソッドは、両方の引数に対してnilを指定してinit(nibName nibNameOrNil: String!, bundle nibBundleOrNil: NSBundle!)を呼び出します(UIViewControllerでCommandキーを押しながらクリックすると、その情報が表示されます)。

TL; TRUIViewControllersを使用してプログラムで作業する場合は、カスタム引数を使用して新しい初期化子を追加する完全な作業例を次に示します。

class MyCustomViewController: UIViewController {
    var myString: String = ""

    convenience init( myString: String ) {
        self.init()

        self.myString = myString
    }
}
38
Klaas

occulus's答えを改善するには:

init() {
     super.init(nibName: nil, bundle: nil)
}
8
Vyacheslav

更新:リンクを追加

https://developer.Apple.com/documentation/uikit/uiviewcontroller/1621359-init

IOSのドキュメントによると、UIViewControllerの指定初期化子はinitWithNibName: bundle:です。

UIViewControllerをサブクラス化する場合、NIBを使用していない場合でも、このメソッドのスーパー実装を呼び出す必要があります。

次のように行うことができます:

init(objectId : NSManagedObjectID) {

    super.init(nibName: (xib's name or nil'), bundle: nil)

   // other code...
}

または

便利な初期化子として新しい初期化子を宣言します。

 convenience init( objectId : NSManagedObjectID ) {

    self.init()

     // other code...

}

8
NcNc