struct didSet何时会被多个突变变量触发?

时间:2019-11-14 22:29:17

标签: swift

我有一个带有变异函数的结构,该函数可以变异多个变量。我假设结构在每次变量更改时都会更改,因为它是一种值类型。但是,该结构的didSet仅在调用变异函数时被调用一次。有人可以向我解释didSet是如何触发的吗?

struct MutatingStruct {
    var intValue = 0 {
        didSet {
            print("int value didSet")
        }
    }
    var stringValue = "" {
        didSet {
            print("string value didSet")
        }
    }

    mutating func setValues() {
        intValue += 1
        mutateTimesTwo()
    }

    private mutating func mutateTimesTwo() {
        stringValue += "a"
    }
}
class SomeClass {
    var mutatingStruct = MutatingStruct() {
        didSet {
            print("mutatingStruct didSet")
        }
    }

    func setHelpStruct() {
        mutatingStruct.setValues()
    }
}

let someClass = SomeClass()
someClass.setHelpStruct()

预期输出:

int value didSet
mutatingStruct didSet
string value didSet
mutatingStruct didSet

实际输出:

int value didSet
string value didSet
mutatingStruct didSet

1 个答案:

答案 0 :(得分:1)

您是对的!结构是值类型。因此,即使更改,它们也会被复制!

想象一下:

  • 使用原始结构的复制值初始化的新实例。
  • intValue获取新值(在复制的实例中)
  • stringValue获取新值(在复制的实例中)
  • mutatingStruct(原始)获取新值(替换为修改后的复制实例

值类型被视为单个值,即使它们具有多个属性。因此,只有从mutating func返回后,他们才能获得更改。因此,项目符号1和2将更改克隆的实例,而项目符号3(最后一个)将更改原始结构。

请记住,Swift比它聪明得多,它将不!一遍又一遍地复制所有内容(在幕后)。但是行为似乎是这样。仅当您有权访问相同值类型的先前版本和新版本并且其中一个已更改时,才会执行实际的复制操作。

在Swift(在后台)中,值类型是引用类型,从调用者的角度来看,它像原始类型一样起作用!

您可以阅读此答案的注释以进一步阐明。