swift - Swift UINavigationController 子类中的强制初始化覆盖

原文 标签 swift overriding

我目前正在子类化 UINavigationController对于服务于 View Controller 流程的框架(在某种程度上,如 UIImagePickerController 做)

这是我的一个实现示例,简化为尽可能简单,可以在操场上运行。

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文档说:

If you subclass UIViewController, you must call the super implementation of this method, even if you aren't using a NIB. (As a convenience, the default init method will do this for you, and specify nil for both of this methods arguments.)



但是我的init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?)覆盖被调用,来自 super.init(rootViewController: viewController)初始化!
没有覆盖它,我猜 UIViewController 的 init(nibName:bundle:)应该被调用,但不是。

我仍然无法理解为什么要覆盖该方法并调用 super使程序运行得更好。 IMO,仅调用 super.thisMethod 时覆盖方法完全没用,它只是在调用堆栈中添加了一个方法调用。

我一定遗漏了一些关于 Swift init 方法的要点,但我不知道是什么。

最佳答案

这是因为 Swift 继承初始化器的方式。如果您没有在当前类中声明任何初始化器,编译器将从父类继承所有初始化器。但是,如果您覆盖/添加新的初始化程序(并且您使用 init(anyVar:) 执行此操作),Swift 将不会自动从父类继承初始化程序,因此无法从导致运行时崩溃的子类访问它们。

如果您对超出此行为的原因感兴趣,可以查看 Intermediate Swift部分和 WWDC 2014(大约 34 分钟标记他们正在谈论初始化器继承)

关于swift - Swift UINavigationController 子类中的强制初始化覆盖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38028940/

相关文章:

ios - 在Swift中将多个参数传递给UIAlertAction

ios - iOS/Swift无法向子类添加手势

ios - iOS共享扩展异常(exception)-项目配置

javascript - 覆盖CSS规则

javascript - 检查“未定义”时,JavaScript变量值将被覆盖

c++ - 尝试覆盖方法时,C++无法实例化抽象类

ios - 如何在CoreData中保存位置

swift - TableViewController的第二次创建与第一个有关的SIGABRT错误

objective-c - 如何使用更具体的类型覆盖父类(super class)的属性?

android - 问题覆盖方法