Swift 读取属性时调用WillSet

Swift 读取属性时调用WillSet,swift,Swift,我在Swift 2中遇到了一个奇怪的情况,在特定情况下,当我引用一个属性时,会调用属性的集观察者 以下代码示例说明了该问题: var i = 0 protocol PropertyProtocol { var name: String { get } } class PropertyType: PropertyProtocol { var name = "Bob" } class AggregateType { var prop: PropertyProtocol! {

我在Swift 2中遇到了一个奇怪的情况,在特定情况下,当我引用一个属性时,会调用属性的
观察者

以下代码示例说明了该问题:

var i = 0

protocol PropertyProtocol {
  var name: String { get }
}

class PropertyType: PropertyProtocol {
  var name = "Bob"
}

class AggregateType {
  var prop: PropertyProtocol! {
    willSet {
      i += 1
      print("a set will be done")
    }
  }
}

let a = AggregateType()
i                          // i = 0, since prop was not set.
a.prop = PropertyType()
i                          // i = 1, since prop was just set.

// This is where it gets weird
a.prop.name
i                          // i = 2
a.prop.name
i                          // i = 3
此问题在Swift 2之前不会出现,因为Xcode 6.4中的相同代码不会重现此问题,但会保留
i=1
,无论调用
a.prop.name
多少次

我为这个问题找到的一个临时解决方法是将内部属性转移到当前范围内的另一个临时变量,并使用temp var引用其内部属性

i                          // i = 1
let prop = a.prop
prop.name
i                          // 1 = 1
但是这使得我的代码更加丑陋,除了为了弥补这个错误


有人知道这个问题吗?有没有办法从根本上解决这个问题?

这是一个在Xcode 7.2 beta 2中已经修复的错误。从 发行说明:

在以前的Swift版本中,如果类型的可变属性为 协议类型,对该属性属性的“链接”访问为 始终被视为属性的突变,即使第二个 属性仅被读取,未被写入。

解决方法是将访问拆分为单独的表达式…

此错误现已修复。(22953072)

这里建议的解决方法正是您已经想到的