【问题标题】:Swift didSet does not fireSwift didSet 不会触发
【发布时间】:2017-03-30 07:45:00
【问题描述】:

假设我有一个具有 3 个属性的练习集类: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成为一个结构:)

标签: swift computed-properties didset


【解决方案1】:

这很可能是因为ExerciseSet 是一个类,这意味着它是一个引用类型。

只需将引用类型变量视为存储数字。然后这些数字指向实际的ExerciseSet 在内存中的位置。换句话说,[ExerciseSet] 本质上是一个数字数组。

当你这样做时:

exerciseSets[index].isEnabled = !exerciseSets[index].isEnabled

您没有更改数组中的任何“数字”。您只在特定索引处查找“数字”,然后使用该“数字”来查找ExerciseSet 对象。之后,设置ExerciseSet 的属性。

如您所见,您根本没有修改数组中的“数字”!

另一方面,您的第二段代码调用didSet,因为您告诉它丢弃特定索引处的元素并将指向set 的“数字”放在该索引处。由于您要取出数组的一个元素并将某些内容放回原处,因此您正在 更改 数组本身!因此,didSet 被调用。

【讨论】:

    【解决方案2】:

    仇恨是一个强烈的词:)

    在这一行:

    exerciseSets[index].isEnabled = !exerciseSets[index].isEnabled
    

    您实际上并没有直接更改您的exerciseSets 数组中的任何内容,您正在更改该数组中特定 ExerciseSet 项目上的某些内容。

    比较一下:

    let set = exerciseSets[index]
    set.isEnabled = !set.isEnabled
    exerciseSets[index] = set
    

    这里您正在更改exerciseSets 数组中的一个实际项目,因此didSet 被触发。

    你能做点什么吗?好问题:) 你需要以某种方式更新exerciseSets 数组以强制didSet 所以我认为你不能比上面的三行短很多。我希望我错了。

    是的,与其说是一个答案,不如说是一个评论,希望你无论如何都能使用它。

    【讨论】:

      【解决方案3】:

      为什么会这样?

      didSet 在您更改属性的值时触发,例如当数组本身发生更改时。

      这里

      exerciseSets[index].isEnabled = !exerciseSets[index].isEnabled
      

      更改了数组中某些对象的属性,但数组保持不变,并且包含相同的对象。所以didSet 不会被调用。

      我可以以某种方式使用前一个选项吗?

      不,你不能。使用后者。

      编辑:我检查了@martin-r 建议将结构用于ExerciseSet,它有效,didSet 被调用。因为当结构的属性值更改时,基本上意味着创建新结构,其中所有未更改的字段都被复制。

      【讨论】:

        【解决方案4】:

        didSet 触发器适用于集合,但不适用于其内容。换句话说,更改集合中存储的对象会触发块,但更改对象的内容不会。这就是为什么您的第一个选项不起作用而第二个选项起作用的原因。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-07-08
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多