1

配列内の要素の値が変更されたかどうかを知る方法は? 、答えは、配列が変更されたかどうかを確認するためにプロパティ オブザーバーを使用することでした。

ただし、プロパティ オブザーバーのコレクション型で更新された要素を特定するにはどうすればよいですか? 例えば:

class MyClass {
    var strings: [String] = ["hello", "world", "!"] {
        didSet(modifiedStrings) {
            print("strings array has been modified!!:")
            print(modifiedStrings)
        }
    }
}

let myClass = MyClass()
myClass.strings.append("a string")
myClass.strings[0] = "Hello"
myClass.strings.removeLast()

追加、更新、または削除操作ごとにコードが呼び出されていることに注意してください。ただしdidSet、影響を受ける要素を正確に知るにはどうすればよいでしょうか。strings配列をProperty Observerとして宣言することでこれを達成する方法さえありますか?

Swift のすべてのコレクション タイプについて質問しています。これは、すべてのコレクション タイプで同じ動作であると想定しているためです。これは観察に関するものです。

ありがとう。

4

2 に答える 2

5

@hnh に感謝します。彼の回答に基づいて、私は次のようになりました。

class MyNumber: NSObject {

    // NOTE that it works in both "willSet" and "didSet"

    /// Array ///
    var arrayNumbers: [String] = ["one", "two", "three"] {
        willSet {
            let oldStrings = Set(arrayNumbers)
            let newStrings = Set(newValue)

            print("removed from array: \(oldStrings.subtracting(newStrings))")
            print("added to array:   \(newStrings.subtracting(oldStrings))")

            print("----------")
        }
    }

    /// Set ///
    var setNumbers: Set = ["one", "two", "three"] {
        didSet(newSet) {
            print("removed from set: \(newSet.subtracting(setNumbers))")
            print("added to set:   \(setNumbers.subtracting(newSet))")

            print("----------")
        }
    }

    var dictionaryNumbers = ["1": "one", "2": "two", "3": "three"] {
        didSet(modified) {
            let oldKeys = Set(dictionaryNumbers.keys)
            let newKeys = Set(modified.keys)

            let oldValues = Set(dictionaryNumbers.values)
            let newValues = Set(modified.values)

            print("removed from dictionary (keys): \(newKeys.subtracting(oldKeys)) (values): \(newValues.subtracting(oldValues))")
            print("added to dictionary (keys):   \(oldKeys.subtracting(newKeys)) (values):    \(oldValues.subtracting(newValues))")
            print("----------")

//            print("removed (values): \(newValues.subtracting(oldValues))")
//            print("added (values):   \(oldValues.subtracting(newValues))")

        }
    }
}

実行:

let myNumber = MyNumber()

/// Array ///

// adding:
myNumber.arrayNumbers.append("four")
/* Logging:
 removed: [] means that nothing has been removed form the array
 added:   ["four"]
 ----------
 */

// updating:
myNumber.arrayNumbers[0] = "One"
/* Logging:
 removed: ["one"]
 added:   ["One"]
 ----------
 */

// deleting:
myNumber.arrayNumbers.removeLast()
/* Logging:
 removed: ["four"]
 added:   [] means that nothing has been added to the array
 ----------
 */


/// Set ///

// adding:
myNumber.setNumbers.insert("four")
/* Logging:
 removed from set: [] means that nothing has been removed form the set
 added to set:   ["four"]
 ----------
 */

// deleting:
myNumber.setNumbers.removeFirst()
/* Logging:
 removed from set: ["three"] // sets are unsorted...
 added to set:   [] means that nothing has been added to the set
 ----------
 */


/// Dictionary ///

// adding:
myNumber.dictionaryNumbers["4"] = "four"
/* Logging:
 removed from dictionary (keys): [] (values): []
 added to dictionary (keys):   ["4"] (values):    ["four"]
 ----------
 */

// updating:
myNumber.dictionaryNumbers["1"] = "One"
/* Logging:
 removed from dictionary (keys): [] (values): ["one"]
 added to dictionary (keys):   [] (values):    ["One"]
 ----------
 */

// deleting:
myNumber.dictionaryNumbers.removeValue(forKey: "2")
/* Logging:
 removed from dictionary (keys): ["2"] (values): ["two"]
 added to dictionary (keys):   [] (values):    []
 ----------
 */

これは、配列、セット、および辞書を処理する方法を示しています。

于 2016-12-13T15:01:37.173 に答える
4

willSetオブザーバーを使用して、変更が適用される前に変更を計算できます。そのようです:

struct YourStruct {
  var strings : [ String ] = [ "Hello", "World", "!" ] {
    willSet {
      // in here you have `newValue` containing the new array which
      // will be set. Do any comparison operations you want, like:
      let oldStrings = Set(strings)
      let newStrings = Set(newValue)
      print("removed: \(oldStrings.substract(newStrings))")
      print("added:   \(newStrings.substract(oldStrings))")
      // (Just for demonstration purposes, if they are Sets, they
      //  should be Sets in the first place, obviously.)
    }
  }
}
于 2016-12-13T12:18:51.230 に答える