我目前正在为一个框架编写子类化的UINavigationController
,该框架提供了一种视图控制器流(有点像UIImagePickerController
)。
下面是我的一个实现示例,已经简化为尽可能简单,并可以在playground中运行。
import UIKit
public class MyNavigationController: UINavigationController {
public var anyVar: Int?
public init(anyVar: Int) {
let viewController = UIViewController()
super.init(rootViewController: viewController)
self.anyVar = anyVar
}
required public init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}
let navigationController = MyNavigationController(anyVar: 42)
最后一行崩溃了,出现了 EXC_BAD_INSTRUCTION
错误。当我在 Xcode 中运行时,它告诉我在运行时 缺少 init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?)
方法。
如果我重写该方法:
public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}
......一切都运行良好,您可以尝试使用自己的播放区。
我不明白为什么。这对我来说听起来不合逻辑。
UIViewController
文档说:
如果您子类化UIViewController,则必须调用此方法的超级实现,即使您不使用NIB。(作为方便,default init方法将为您执行此操作,并为这两个方法参数指定nil)。
但是我的init(nibName nibNameOrNil:String?,bundle nibBundleOrNil:NSBundle?)
覆盖被调用,来自super.init(rootViewController: viewController)
初始化!
没有覆盖它,我猜UIViewController的init(nibName:bundle:)
应该被调用,但不是。
我仍然无法理解为什么重写方法并调用super
会使程序更加有效。在我看来,只调用super.thisMethod
就覆盖一个方法完全没有意义,它只会在调用堆栈中添加一个方法调用。
我似乎缺少了有关Swift初始化方法的一些基本知识,但是我无法想出是什么。