deinit末尾的Defer语句会产生警告

时间:2019-03-27 21:12:20

标签: swift deinit property-observer

由于 Xcode 10.2 (快速5)defer范围末尾的deinit语句产生:

  范围结束之前的

'defer'语句总是立即执行;替换为“ do”语句以消除此警告

让我们看一下这个例子:

var foo: String {
    didSet {
        // smt
    }
}

deinit {
    defer { <--- Warning
        foo = bar
    }
}
  • 当然,可以通过将代码从观察者移动到方法并显式调用它来摆脱此警告,但是……

此警告的含义是什么?-在defer中包含deinit语句是否合理? (例如,能够触发属性的观察者)

1 个答案:

答案 0 :(得分:4)

该警告是正确的,因为此处使用defer不会更改程序的执行顺序,这是该语句的设计目的。但是,不幸的是,建议的替代方案否则会改变程序的行为(提交错误:SR-10207)。

值得注意的是,使用defer来触发属性观察器是一种小技巧,它只能起作用,因为类型检查器认为它与deinit主体是不同的上下文。您也可以使用闭包表达式实现相同的结果:

  deinit {
    { foo = bar }()
  }

理想情况下,会有某种形式的语法让您告诉Swift“不要在这里执行直接存储访问”,因此这种变通方法不是必需的,但目前还没有。

>

一种不太麻烦的解决方法是将反初始化程序的所需逻辑提取到一个单独的方法中,该方法将逻辑置于正常进行属性访问的上下文中:

class C {
  var bar = ""

  var foo: String {
    didSet {
      // smt
    }
  }

  init(foo: String) { self.foo = foo }

  private func doDeinit() {
    foo = bar
  }

  deinit {
    doDeinit()
  }
}