2016-12-13 67 views
0

在回答How do I know if a value of an element inside an array was changed?的問題時受到啓發,答案是使用屬性觀察器檢查數組是否已被修改。如何使用屬性觀察器觀察具有Swift集合類型的特定元素?

但是,如何確定屬性觀察器中集合類型的更新元素是什麼?例如:

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數組作爲屬性觀察者來實現此目的?

我在Swift中詢問所有的集合類型,因爲我認爲它應該是所有這些類型的相同行爲,它是關於觀察的。

感謝。

回答

1

感謝@ HNH的基礎上,他answer,我結束了:

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): [] 
---------- 
*/ 

這說明如何處理陣列,設置和字典。

3

您可以使用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.) 
    } 
    } 
} 
+1

非常好的答案。你在印刷結束時忘了「)」。 + 1 – Rob

+2

與'didSet'中的'oldValue'比較也可以。 –

+0

謝謝你的回答。這聽起來合乎邏輯,我只是​​添加了一個基於你的答案,展示瞭如何處理數組,字典和集合。對於數組有一個特殊情況(因爲它是唯一排序的)我無法實現(因爲您正在將其更改爲設置 - 未檢測到相減時 - 檢查相減時),這是知道修改過的元素的索引,你有什麼想法,我該怎麼做?順便說一句,我會等待檢查是否有任何新的答案將被接受之前接受你的答案:) –