【问题标题】:Swift 1.2: 'self' used before super.init callSwift 1.2:在 super.init 调用之前使用“self”
【发布时间】:2015-04-10 01:01:38
【问题描述】:

我有这个代码:

class SomeViewController : UIViewController {

 let deferred : ()->()

 required init(coder aDecoder : NSCoder) {
    deferred = {
        self.doSomething()
    }

    super.init(coder: aDecoder)
 }

 func doSomething() {
    // Does things....
 }

}

在 Swift 1.2 中编译失败并出现错误:

'self' 在 super.init 调用之前使用

在 1.2 之前的日子里,我们可以通过多种方式解决这个问题,例如隐式展开条件。这种方法将不再有效。

我已经看到其他答案参考 2 阶段初始化或惰性装饰器,但都牺牲了属性的不变性。当然,这在 Swift 1.2 中肯定是可以解决的,但我没有想法。

【问题讨论】:

  • 您是否有理由不能简单地将呼叫转移到super您使用self 之前?这正是错误告诉您的内容,我没有理由查看代码为什么这不应该是好的,而且您没有解释任何原因。
  • @nhgrif:但是在self(包括deferred属性)完全初始化之前,你不能调用super.init()
  • @MartinR 哦,我明白了。现在有道理了。除了...如果这行得通,它不会在self 上创建一个保留周期吗?
  • @nhgrif:是的,但这是一个不同的问题(可以通过弱捕获self 来解决)。
  • @MattD 因为您实际上并没有向self 发送消息,而只是在构建匿名函数的过程中引用它,所以这将是提交错误报告的一个很好的用例。苹果在 Swift 1.2 中关闭了一些关于初始化的漏洞,他们可能把门关得更紧了。

标签: swift


【解决方案1】:

这是一个临时解决方法:

private(set) var deferred : ()->() = { }

required init(coder aDecoder : NSCoder) {
    super.init(coder: aDecoder)
    self.deferred = {
        self.doSomething()
    }

}

我的想法是,好吧,我们确实“牺牲了属性的不变性”,但从公共的角度来看,属性仍然是不可变的,因为 setter 是私有的。

【讨论】:

  • 我会归档的。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多