假设我有一个具有3个属性的ExerciseSet类:id,name,isEnabled。
我有这个类的对象数组:
var exerciseSets: [ExerciseSet] = [] {
didSet {
ExerciseSet.syncWithPList(updatedSets: exerciseSets)
}
}
代码中的某处我执行以下操作:
exerciseSets[index].isEnabled = !exerciseSets[index].isEnabled
但是在这种情况下didSet不会触发。只有我这样写:
let set = exerciseSets[index]
set.isEnabled = !set.isEnabled
exerciseSets[index] = set
为什么会这样?我可以以某种方式使用前一个选项吗?后者似乎很冗长,我讨厌它。
答案 0 :(得分:2)
这很可能是因为ExerciseSet
是一个类,这意味着它是一个引用类型。
只需将引用类型变量视为存储数字即可。然后,这些数字指向实际ExerciseSet
位于内存中的位置。换句话说,[ExerciseSet]
本质上是一个数字数组。
执行此操作时:
exerciseSets[index].isEnabled = !exerciseSets[index].isEnabled
您没有更改任何"数字"在数组中。你只找了"号码"在特定的索引处,您使用" number"找到ExerciseSet
对象。之后,您设置了ExerciseSet
。
正如您所看到的,您没有修改"数字"在阵列中!
另一方面,你的第二段代码会调用didSet
,因为你要告诉它将元素丢弃在特定的索引处,然后输入"数字"指向该指数的set
。既然您正在搜索阵列中的某个元素并重新放入某些内容,那么您就可以更改阵列本身!因此,didSet
被调用。
答案 1 :(得分:1)
仇恨是一个强有力的词:)
在这一行:
exerciseSets[index].isEnabled = !exerciseSets[index].isEnabled
您实际上并未在exerciseSets
数组中直接更改 中的任何内容,而是在特定 ExerciseSet
项目中更改某些内容那个阵列。
将其与:
进行比较let set = exerciseSets[index]
set.isEnabled = !set.isEnabled
exerciseSets[index] = set
您要在exerciseSets
数组中更改实际项目,因此会didSet
被解雇。
exerciseSets
数组以强制didSet
,所以我不认为你可以比上面的三行短得多。我希望我错了。
是的,不是作为评论的答案,希望你无论如何都可以使用它。
答案 2 :(得分:0)
didSet
触发器适用于集合,但不适用于其内容。换句话说,更改集合中存储的对象会触发块,但更改对象的内容则不会。这就是为什么你的第一个选项不起作用而第二个选项不起作用的原因。
答案 3 :(得分:0)
didSet
,例如,当数组本身发生更改时会发生这种情况。
下面
exerciseSets[index].isEnabled = !exerciseSets[index].isEnabled
你更改数组中某个对象的属性,但数组保持不变,并包含相同的对象。因此didSet
不会被召唤。
不,你不能。使用后者。
编辑:我检查了@ martin-r建议使用ExerciseSet
的结构,并且它有效,didSet
set被调用。因为当结构的属性值改变时,基本上意味着创建新的结构,而只有被改变的字段被复制。