0

id、name、isEnabled の 3 つのプロパティを持つクラス ExerciseSet があるとします。

私はこのクラスのオブジェクトの配列を持っています:

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

なぜそうなのですか?どうにかして前者のオプションを使用できますか? 後者は冗長に思えますが、私はそれが嫌いです。

4

4 に答える 4

2

これはおそらくExerciseSetクラスであり、参照型であるためです。

参照型変数は、数値を格納するものと考えてください。ExerciseSetこれらの数値は、実際のメモリ内の場所を指します。つまり[ExerciseSet]、本質的には数値の配列です。

これを行う場合:

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

配列内の「数字」を変更していません。特定のインデックスで「番号」のみを探し、その「番号」を使用してExerciseSetオブジェクトを見つけます。その後、 のプロパティを設定しますExerciseSet

ご覧のとおり、配列内の「数値」はまったく変更されていません。

一方、コードの 2 番目の部分はdidSet、特定のインデックスで要素を破棄し、そのインデックスを指す「番号」を配置するように指示しているため、 を呼び出しsetます。配列の要素を取り出して何かを戻すので、配列自体を変更しています! したがって、didSetと呼ばれます。

于 2016-11-16T08:04:12.263 に答える
1

憎しみは強い言葉です:)

この行で:

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

実際には配列内で直接何かを変更しているわけではなく、その配列内の特定の項目でexerciseSets何かを変更しています。 ExerciseSet

それを比較してください:

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

ここでは、配列内の実際のアイテムを変更しているため、発生します。exerciseSetsdidSet

それについて何かできることはありますか?exerciseSets良い質問です:)何らかの方法で配列を強制的に更新する必要があるdidSetため、上記の3行よりもずっと短くすることはできないと思います。私が間違っていることを願っています。

ええ、コメントほどの答えではありませんが、とにかくそれを使用できることを願っています.

于 2016-11-16T08:04:05.100 に答える
0

なぜそうなのですか?

didSetプロパティの値を変更すると発生します。たとえば、配列自体が変更された場合です。

ここ

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

配列内の一部のオブジェクトのプロパティを変更しますが、配列は同じままで、同じオブジェクトが含まれています。だからdidSet呼ばれない。

どうにかして前者のオプションを使用できますか?

いいえ、できません。後者を使用してください。

編集: @martin-r のアドバイスをチェックして、構造体を使用するようにしましたがExerciseSet、動作し、didSetset が呼び出されました。構造体のプロパティ値が変更された場合、基本的には、変更されたフィールドを除くすべてがコピーされた新しい構造体の作成を意味するためです。

于 2016-11-16T08:04:46.697 に答える