为什么我不能在 Swift 中调用 UIViewController 上的默认 super.init() ?

我没有使用一个故事板的 UIViewController,我想有一个自定义的 init函数,其中我传递了一些对象的 NSManagedObjectID。我只是想调用 super.init(),就像我在 Objective-C 中所做的那样。像这样:

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

但我得到了下面的编译器错误:

必须调用超类 UIViewController 的指定初始值设定项

我能不能不要再这么做了?

70663 次浏览

The designated initialiser for UIViewController is initWithNibName:bundle:. You should be calling that instead.

See http://www.bignerdranch.com/blog/real-iphone-crap-2-initwithnibnamebundle-is-the-designated-initializer-of-uiviewcontroller/

If you don't have a nib, pass in nil for the nibName (bundle is optional too). Then you could construct a custom view in loadView or by adding subviews to self.view in viewDidLoad, same as you used to.

Another nice solution is to declare your new initializer as a convenience initializer as follows:

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


// ... store or user your objectId
}

If you declare no designated initializers in your subclass at all, they are inherited automatically and you are able to use self.init() within your convenience initializer.

In case of UIViewController the default init method will call init(nibName nibNameOrNil: String!, bundle nibBundleOrNil: NSBundle!) with nil for both arguments (Command-Click on UIViewController will give you that info).

TL;TR: If you prefer to programmatically work with UIViewControllers here is a complete working example that adds a new initializer with a custom argument:

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


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


self.myString = myString
}
}

Update: add the link

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

According to the documentation for iOS, the designated initialiser for UIViewController is initWithNibName: bundle:.

If you subclass UIViewController, you must call the super implementation of this method, even if you aren't using a NIB.

You can do it as follows:

init(objectId : NSManagedObjectID) {


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


// other code...
}

or

Declare a new initializer as a convenience initializer:

 convenience init( objectId : NSManagedObjectID ) {


self.init()


// other code...

}

To improve the occulus's answer:

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