让我们从一些代码段开始
struct DigitS {
var number = 42
init(_ n: Int) {
self.number = n
}
mutating func replace() {
self = DigitS(12) // mutating
}
}
class DigitC {
var number = 42
init(_ n: Int) {
self.number = n
}
func replace() {
self = DigitC(12) //#Cannot assign to value: "self" is immutable
}
}
很长一段时间,我对可变,可修改的含义感到非常困惑。以下是我目前的一些理解,如果你能指出它可能存在的所有错误,那就太好了
上述结构类型中的变异函数不会发生变异"实例,它将用一个全新的
变异意味着:分配,初始化或变异功能等操作不会修改当前值,但会触发替换
类类型变量的值是不可变的,但您可以修改/更改当前值(这是编译器发出警告的原因,请参阅带#的注释)
只有在类型为值类型时才能调用setter观察者,因为setter会告诉变量是否已被变异/替换(请参阅下面的代码)
struct Digit {
var number = 12
}
var b = Digit() {
didSet{ print("number is set") }
}
b.number = 22 // observer is called
class Digit {
var number = 12
}
var b = Digit() {
didSet{ print("number is set") }
}
b.number = 22 // observer is not called
感谢您的时间和帮助
答案 0 :(得分:1)
使用图像可以更好地解释处理内存问题,但我会在这里试一试:
给出一个带有mutator的简单结构:
struct Example {
var text: String
mutating func changeText(to newText: String) {
self.text = newText
}
}
let constantExample = Example(text: "Test") //Makes a section of memory that isn't allowed to change.
constantExample.changeText(to: "Other Test") //This doesn't work because constantExample isn't mutable.
var mutableExample = Example(text: "Test") //Makes a section of memory that is allowed to change.
mutableExample.changeText(to: "Other Test") //This doesn't make a new copy, but rather changes the value in mutableExample's section of memory
如果你要使用你提到的具体案例:
mutating func changeText(to newText: String) {
self = Example(text: "A new text")
}
mutableExample仍将驻留在同一内存位置,但您手动创建一个全新的Example实例,然后将该数据从该实例复制到mutableExample。
相反:) Mutating就地更改实例。您可以通过复制不同的值来更改该实例(如self =
示例中所示),但实例仍然是相同的实例,只是具有不同的值。
创建类变量时,您正在为内存部分创建引用。设置或更改引用var variableName = classInstance
时,引用的位置在初始化后保持不变,但引用的位置(如果var)可以更改。
你的功能正确,但缺少一些细微差别。在结构示例中,如前所述,实例的实际值正在发生变化。在类示例中,引用的内存正在更改,但b
中存储的实际值不会更改。
答案 1 :(得分:0)
观察者观察值的变化,类型变量的值是对象的参考点。要触发属性观察者,必须更改引用。
class Digit {
var number = 12
}
var a = Digit()
var b = Digit() {
didSet{ print("number is set") }
}
b.number = 22 // observer is called
b = a //observer is called here!!