当我读取属性时调用WillSet

Avi*_*ion 3 swift

我在Swift 2中有一个奇怪的情况,在某种情况下,当我引用一个属性时,属性的set观察者被调用.

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

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
Run Code Online (Sandbox Code Playgroud)

这个问题在Swift 2之前没有出现,因为Xcode 6.4中的相同代码不会重现问题,但i = 1无论a.prop.name调用多少次都会保留.

我发现此问题的临时解决方法是将内部属性转移到当前作用域中的另一个临时变量,并使用temp var引用其内部属性.

i                          // i = 1
let prop = a.prop
prop.name
i                          // 1 = 1
Run Code Online (Sandbox Code Playgroud)

但这使我的代码更加丑陋,除了弥补这个错误.

谁知道这个问题?反正有没有从根本上解决这个问题?

Mar*_*n R 6

这是一个已在Xcode 7.2 beta 2中修复的错误.来自发行说明:

在以前的Swift版本中,如果类型具有协议类型的可变属性,则对该属性的属性的"链接"访问始终被视为属性的突变,即使第二个属性仅被读取而未被写入.
...
解决方法是将访问分成单独的表达式......
...
此错误现已得到修复.(22953072)

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