Swift:使用didSet数组进行细粒度观察



如果我们在swift类中的Array属性上提供一个didSet观察器,那么我们将能够观察到整个数组的变化。我们如何对数组进行细粒度观察,从而跟踪插入、更新和删除?仅仅使用didSet观察者似乎无济于事。知道怎么做吗?我偶然发现了一个链接这似乎解释了我想要的东西,但理解起来有些复杂。有人能提供一个简单的例子来解决这个问题吗?感谢

如果要在设置属性之前调查"旧"值(以计算差异),则需要使用willSet,而不是didSet。在didSet中,计算的变化为时已晚(显然…)

样品:

class AWrap {
  var values : [ String ] = [] {
    willSet {
      print("values: (values)")
      print("   new: (newValue)")
      let old = Set(values)
      let new = Set(newValue)
      let newElements  = new.subtracting(old)
      let goneElements = old.subtracting(new)
      print("     +: (newElements)")
      print("     -: (goneElements)")
    }
  }
}

运行:

let a = AWrap()
a.values.append("2")
a.values.append("3")
a.values.remove(at:0)

提供:

values: []
   new: ["2"]
     +: ["2"]
     -: []
values: ["2"]
   new: ["2", "3"]
     +: ["3"]
     -: []
values: ["2", "3"]
   new: ["3"]
     +: []
     -: ["2"]

如果要在以下几个地方进行检测,您可以在扩展中推广检测,使其更易于管理:

 extension Array where Element:Comparable
 {
    func changesFrom(old:[Element]) -> [(index:Int, mod:String, old:Element, new:Element, desc:String)]
    {
       var changes:[(index:Int, mod:String, old:Element, new:Element, desc:String)]
           changes  =  zip(old,self).enumerate()
                      .filter{ $1.0 != $1.1 }
                      .map{ ($0, "∆", $1.0, $1.1 , "($1.0) -> ($1.1)") }
           changes +=  (old.count..<max(old.count,self.count))
                      .map{ ($0, "+", self[$0], self[$0], "(self[$0])") }
           changes +=  (self.count..<max(old.count,self.count))
                      .map{ ($0, "-", old[$0], old[$0], "(old[$0])" ) }
       return changes
    } 
    func printChangesFrom(old:[Element])
    {
       for changed in changesFrom(old)
       { 
         print( "[(changed.index)] (changed.mod) (changed.desc)" )
       }
    }
 }
 class ContainsArray
 {
    var array  = [1,2,3,4]
    {
       didSet 
       { 
         array.printChangesFrom(oldValue)
       }
    }
 }

 var CA = ContainsArray()
 print("change an element")
 CA.array[2] = 7  
 //[2] ∆ 3 -> 7
 print("change multiple elements")
 CA.array.sortInPlace(<)
 //[2] ∆ 7 -> 4
 //[3] ∆ 4 -> 7
 print("add elements")
 CA.array += [9,12,14]
 //[4] + 9
 //[5] + 12
 //[6] + 14     
 print("remove Elements")
 CA.array.removeLast(3)
 //[4] - 9
 //[5] - 12
 //[6] - 14

最新更新