【问题标题】:Swift: Array fine grained observation using didSetSwift:使用 didSet 进行数组细粒度观察
【发布时间】:2016-07-23 20:05:02
【问题描述】:

如果我们在 swift 类的 Array 属性上提供 didSet 观察者,那么我们将能够观察整个数组的变化 我们如何对数组进行细粒度观察,以便能够跟踪插入、更新和删除?似乎仅仅使用 didSet 观察者并没有帮助。知道怎么做吗?我遇到了link 这似乎解释了我正在寻找的东西,但理解起来有些复杂。谁能提供一个简单的例子来解决这个问题? 谢谢

【问题讨论】:

    标签: ios swift


    【解决方案1】:

    如果您想在设置属性之前调查“旧”值(计算差异),您需要使用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"]
    

    【讨论】:

    • "在 didSet 中计算变化为时已晚" 出于好奇,您为什么反对在 didSet 中使用“oldValue”魔法变量?
    • 不要断章取意。我不反对,它适用于“设置属性之前”。
    【解决方案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
    

    【讨论】:

      猜你喜欢
      • 2021-12-23
      • 1970-01-01
      • 2018-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-20
      • 2017-12-03
      • 1970-01-01
      相关资源
      最近更新 更多