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

标签 swift overriding

我目前正在为服务 View Controller 流的框架子类化 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)
}

...一切正常:您可以尝试使用自己的 Playground 。

我不明白为什么。这对我来说听起来不合逻辑。

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?) override 被调用,来自 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/

相关文章:

swift: prepareForSegue indexPathForSelectedRow

oop - 是否可以从 Golang 中的父结构调用覆盖的方法?

C++ 抽象类和创建派生类

ios - 为什么它无法识别扩展中的这种类型?

ios - 协议(protocol)上的 Swift Equatable

ios - Swift:应用程序因 EXC_BAD_INSTRUCTION 错误而崩溃?

Angular Material 排版覆盖 - 将 2 个配置传递给 mat-core?

java - 如何重写泛型方法

swift 。让我们重写但不调用该方法

ios - UICollectionView 的单元格选择在 swift 中不起作用