无法使用Swift中的存储属性覆盖

时间:2018-04-03 22:43:20

标签: swift override

在Swift 4.1中覆盖lazy var的正确方法是什么? 以下代码在swift 4.0中工作正常但是由于swift 4.1我在覆盖时有警告,所以我猜它在swift 5中不可用

我曾经:

class A {

    lazy var myVar: String = {
        return "A"
    }()
}

class B: A {

    override lazy var myVar: String = { // WARNING Cannot override with a stored property myVar
        return "B"
    }()
}

我想这是这样的,但它不性感......

class A {

    lazy var myVar: String = {
        return createMyVar()
    }()

    func createMyVar() -> String {
        return "A"
    }
}

class B: A {

    override func createMyVar() -> String {
        return "B"
    }
}

2 个答案:

答案 0 :(得分:9)

虽然没有技术上的理由为什么你不能用引入存储的属性覆盖属性(虽然它可能会引起观察者覆盖的歧义;参见this Q&A for more info),但Swift目前还不允许你这样做。

事实上,在4.0中,您可以使用lazy属性was unintended覆盖属性(因为覆盖引入了存储),因此您将在4.1中收到警告并在Swift 5模式以保持源兼容性(在#13304中实现)。

但是,您可以通过转发计算属性获得相同的结果:

class A {
  lazy var myVar: String = "A"
}

class B : A {

  // Note that this isn't a particulary compelling case for using 'lazy', as
  // the initialiser expression is not expensive.
  private lazy var _myVar: String = "B"

  override var myVar: String {
    get { return _myVar }
    set { _myVar = newValue }
  }
}

答案 1 :(得分:0)

在ViewController的主Storyboard(包括TableView和其他View Controller)上的对象插座上单击鼠标右键,并检查以确保您没有同时启用两个插座路径。同一对象的两个启用的路径将导致此错误,而删除其中一个路径将消除该错误。为了获得最佳结果,请删除两个出口路径,然后通过从对象到Controller文件创建一个新出口来重新开始。