ios - 为什么我必须为我的编程 UIViewController 子类声明相同的必需但未实现的初始化程序(编码器 aDecoder)?

标签 ios swift uiviewcontroller designated-initializer

也许只有我一个人,但我发现 swift 的某些方面……至少可以说是迟钝。

我大部分时间不使用 Interface Builder,因为我喜欢使用 PureLayout。所以我希望制作一个 UIViewController 子类,比如 PureViewController,它有一个方便的 init 没有参数:

class PureViewController : UIViewController {

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

}

但这不行,因为 XCode 告诉我我还必须实现 init(coder aDecoder: NSCoder)。好的,没关系!这就是我制作这门课的原因 - 所以我不必为子类再次这样做。

class PureViewController : UIViewController {

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

    required init(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

}

好的,现在这是我不明白的。

我定义了一个子类,SomePureViewController : PureViewController,带有初始化器init(viewModel:ICrackersViewModel)...

class SomePureViewController : PureViewController {

    init(viewModel:ICrackersViewModel) {
        super.init()
    }

}

但它仍然要我定义相同的愚蠢初始化程序直到王国来临!

class SomePureViewController : PureViewController {

    init(viewModel:ICrackersViewModel) {
        super.init()
    }

    required init(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

}

现在我明白了这个想法 - 我的子类中没有 init(decoder),即使它是在其父类中定义的。

也许我一直在使用 UIViewController 处理这个问题,但之前从未注意到它。

我的问题如下:

  1. 是否是我做错了什么导致了这种行为?
  2. 除了继承之外,还有什么方法可以避免重复自己吗?
  3. 是否有计划改变这一点?

最佳答案

重点是,只要知道基类型就可以初始化一个可能的派生类。

让我们假设一个基类

class Base {
    let value: Int

    required init(value: Int) {
        self.value = value
    }
}

还有一个函数

func instantiateWith5(cls: Base.Type) -> Base {
    return cls.init(value: 5)
}

那么我们可以做

let object = instantiateWith5(Base.self)

现在如果有人定义了派生类

class Derived: Base {
    let otherValue: Int

    init() {
        otherValue = 1
        super.init(value: 1)
    }

    required init(value: Int) {
        fatalError("init(value:) has not been implemented")
    }
}

我们至少可以打电话

let object2 = instantiateWith5(Derived.self)

违反了 LSP,但那是你的代码的问题,而不是语言的问题。

Swift 必须保证初始化器让你的对象处于初始化状态,即使它们是从基础对象派生的,所以我想改变它是一件坏事。如果您想定义一个不可反序列化的 UIViewController 并因此违反 LSP,这是您的决定 - 但不要指望语言在这方面支持您。

关于ios - 为什么我必须为我的编程 UIViewController 子类声明相同的必需但未实现的初始化程序(编码器 aDecoder)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31866931/

相关文章:

ios - 一个 View Controller 中的两个 TableView

ios - 无法从数据源获取单元格

ios - 数据库目录问题

ios - Facebook Scores API 不发布开放图表故事

ios - 为什么我的 tableview 为每个单元格返回相同的 Parse 图像?

ios - 使用 presentViewController :animated:completion: in iOS 8 时 presentingViewController 为 nil

ios - 与 UIActivityViewController 共享 UiWebView 内容

swift - 绕过 WatchKit 中的 playHaptic 预定义案例

ios - Segue 到 UITableViewController 覆盖导航栏

ios - 如何快速知道一个水龙头是在 View 内还是在 View 外