【问题标题】:Error in Swift class: Property not initialized at super.init call - How to initialize properties which need use of self in their initializer parameterSwift 类中的错误:在 super.init 调用时未初始化属性 - 如何初始化需要在其初始化参数中使用 self 的属性
【发布时间】:2015-01-17 16:15:54
【问题描述】:

我正在快速覆盖UITableViewController,其中我有两个必需的变量,它们使用selfweak 引用进行初始化,因为它们用于实现UITableViewDataSource 协议并需要self 引用使用其tableView 属性

class VideosListViewController: UITableViewController {
  
  required init(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    self.datasourceOfflineVideos = ASDataSource(tableViewController: self)
    self.datasourceOnlineVideos = ASDataSource(tableViewController: self)
  }
  
  // MARK: - Variables
  var datasourceOnlineVideos:ASDataSource
  var datasourceOfflineVideos:ASDataSource
  }

现在的问题是它给了我错误Property not initialized at super.init call,正如这里所解释的那样:Error in Swift class: Property not initialized at super.init call

Swift 的编译器会执行四项有用的安全检查,以确保两阶段初始化完成时不会出错

安全检查 1 指定的初始化程序必须确保其类引入的所有“属性在它委托给超类初始化程序之前都已初始化。

摘自:Apple Inc. “Swift 编程语言”。电子书。 https://itunes.apple.com/us/book/swift-programming-language/id881256329?mt=11

所以我的问题是:

如果 swift 类中的实例变量需要 self 引用来初始化,如这里的 ASDataSource 类型变量,我该怎么做??

由于 swift 不允许我在初始化所有实例变量之前调用 super.init() 并且也不允许我在调用 init() 之前在初始化器中使用 self super.init()

目前我正在使用可选变量来解决问题。但出于学习目的,我想知道如何做到这一点。在此先感谢:)

【问题讨论】:

    标签: ios swift properties compiler-errors initialization


    【解决方案1】:

    您只需要在初始化程序中反转 super.init/properties 的顺序:

     required init(coder aDecoder: NSCoder) {
        self.datasourceOfflineVideos = ASDataSource(tableViewController: self)
        self.datasourceOnlineVideos = ASDataSource(tableViewController: self)
        super.init(coder: aDecoder)
      }
    

    首先出现实例属性,然后可以调用超类初始化程序。但这在您的情况下是不可能的,因为您引用的是self

    在这种情况下,解决方法是使属性隐式展开可选:

    var datasourceOnlineVideos:ASDataSource!
    var datasourceOfflineVideos:ASDataSource!
    

    由于不需要初始化可选项,您可以在调用super.init 方法后安全地初始化它们。隐式展开后,您可以将它们用作任何其他非可选属性。

    Apple 在多个类中使用此模式,包括UIViewController:当您从 IB 添加插座时,组件属性始终声明为隐式展开。那是因为控件本身不是在初始化器中实例化的,而是在后面的阶段。

    【讨论】:

    • 谢谢。这对我有用 :) 还有一件事:在这种情况下,我们需要在初始化数据源变量之前调用 super.init。
    猜你喜欢
    • 2015-07-05
    • 2020-07-06
    • 2014-10-09
    • 2021-12-22
    • 2014-07-24
    相关资源
    最近更新 更多