[英]In Swift, does resetting the property inside didSet trigger another didSet?
[英]Swift didSet does not fire
假设我有一个具有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
为什么会这样呢? 我可以以某种方式使用前一个选项吗? 后者似乎很冗长,我讨厌。
这很可能是因为ExerciseSet
是一个类,这意味着它是一个引用类型。
只需将引用类型变量视为存储数字即可。 这些数字然后指向实际的ExerciseSet
在内存中的位置。 换句话说, [ExerciseSet]
本质上是一个数字数组。
执行此操作时:
exerciseSets[index].isEnabled = !exerciseSets[index].isEnabled
您没有更改数组中的任何“数字”。 您仅在特定索引中查找“数字”,然后使用该“数字”查找ExerciseSet
对象。 之后,您设置了ExerciseSet
的属性。
如您所见,您根本没有修改数组中的“数字”!
在另一方面,你的代码的第二条调用didSet
因为你告诉它,在一个特定的指数扔掉元素,并把指向“数量” set
该索引处。 由于您要设计数组的元素并放回一些东西,因此您要更改数组本身! 因此, didSet
被调用。
仇恨是一个很强的词:)
在这一行:
exerciseSets[index].isEnabled = !exerciseSets[index].isEnabled
您实际上并没有直接在exerciseSets
数组中进行任何更改,而是在该数组中特定的 ExerciseSet
项目上进行了更改。
比较一下:
let set = exerciseSets[index]
set.isEnabled = !set.isEnabled
exerciseSets[index] = set
在这里,您正在更改exerciseSets
数组中的实际项 ,因此将触发didSet
。
你能做些什么吗? 好问题:)您需要以某种方式更新exerciseSets
数组以强制didSet
因此我认为您不能比上述三行短很多。 我希望我是错的。
是的,与其说是评论,不如说是答案,希望您仍然可以使用它。
didSet
触发器适用于集合,但不适用于其内容。 换句话说, 更改对象集中存储的对象将触发该块,但更改对象的内容则不会。 这就是为什么您的第一个选项不起作用而第二个选项却起作用的原因。
当更改属性的值时, didSet
触发,例如,数组本身发生更改时。
这里
exerciseSets[index].isEnabled = !exerciseSets[index].isEnabled
您可以更改数组中某些对象的属性,但是数组保持不变 ,并且包含相同的对象。 所以didSet
将不会被调用。
不,你不能。 使用后者。
编辑:我检查了@ martin-r建议以使用ExerciseSet
结构,它的工作原理是调用didSet
设置。 因为当结构的属性值更改时,基本上意味着要创建新结构,并复制所有更改的字段。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.