swift - 在使用协议(protocol)转换访问计算变量期间调用结构体

标签 swift struct protocols swift2 setter

我已经为遵守协议(protocol)的结构创建了一个全局变量。该变量有一个 setter 观察者,每当设置该变量时,该观察者就会完成任务。由于结构本身遵循协议(protocol),因此我希望变量的类型是协议(protocol)类型。

protocol TestProtocol {
    var someInt: Int {get set}
    var computedVar: Int {get}
    func funcCall() -> Int
}

struct TestStruct: TestProtocol {
    var someInt: Int = 1

    var computedVar: Int {
        return 0
    } 

    func funcCall() -> Int {
        return 2
    }
}

var testProtocolVar: TestProtocol = TestStruct() {
    willSet(newTest) {
        print ("*** Setter testProtocolVar called!!!")
    }
}

问题是,当我获取作为结构中计算属性的协议(protocol)属性的值时,也会调用变量 setter 。

/***
  When a variable is defined and typecast as a protocol, calling a
  computed variable on the variable (a class or a struct) the setter 
  method of the variable will be called (Undesired Behaviour).
***/

print ("\n\n *** Test Protocol Cast Variable *** \n\n")
testProtocolVar
testProtocolVar.someInt
print("Setter has not been called")
testProtocolVar.funcCall()
print("Setter has not been called after function")
testProtocolVar.computedVar
print("Setter has been called when using computed variable")

/*
    *** Test Protocol Cast Variable *** 


   Setter has not been called
   Setter has not been called after function
   *** Setter testProtocolVar called!!!
   Setter has been called when using computed variable
*/

类似的情况,变量是结构类型,不会触发 setter。

print ("\n\n *** Test Normal Cast Variable *** \n\n")

/***
  When a variable is defined and typecast as the struct type, calling a
  computed variable on the variable the setter method of the variable 
  will NOT be called (Desired Behaviour).
***/

var testVar:TestStruct = testProtocolVar as! TestStruct

testVar
testVar.someInt
print("Setter has not been called")
testVar.funcCall()
print("Setter has not been called after function")
testVar.computedVar
print("Setter has not been called when using computed variable")

/*
   *** Test Normal Cast Variable *** 


  Setter has not been called
  Setter has not been called after function
  Setter has not been called when using computed variable
*/

有人能解释为什么调用 setter 观察者吗?

这似乎是 swift 中的一个错误,除非我遗漏了一些东西。

最佳答案

这似乎已在 Xcode 7.2 beta 2 中正式修复

Resolved Issues in Xcode 7.2 beta 2 - Swift 2.1 and Objective-C Swift Compiler In previous releases of Swift, if a type had a mutable property of protocol type, "chained" accesses to properties of that property were always treated as mutations of the property, even if the second property was only read, not written. For example:

  protocol Countable {
       var count: Int { get }
  }
  class MyObject {
      var widgets : Countable {
             didSet { print("in didSet") }
} }
  var obj : MyObject = ...
  let count = obj.widgets.count

This would perform a spurious write back to the property widgets, causing didSet to unexpectedly fire. The workaround was to split the access into separate expressions, like so:

  let widgets = obj.widgets
  let count = widgets.count

This bug has now been fixed. (22953072)

关于swift - 在使用协议(protocol)转换访问计算变量期间调用结构体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32958579/

相关文章:

swift - 未找到框架 FBLPromises(Swift 包管理器)

ios - 使用 UIViewController 子类的子类和 UIView 子类的子类

ios - ScrollView 后 UITableView 的高度发生变化

ios - 类型 'UIViewController' 的值没有成员 'addSubview' Swift2

C# - 调用具有所有默认参数的结构构造函数

c - 与不同的 header 共享数据结构

c# - 如何在 C# 中初始化结构

ios - 如何声明也符合协议(protocol)的特定类的属性?

Swift 类型不符合协议(protocol)

swift - 如何修复 'Swift Protocols/Delegates setting UIImages - Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value'?