2016-07-23 71 views
1

细粒度的观察。如果我们提供的SWIFT类数组属性didSet观察员那么我们就可以观察到阵列作为一个整体的变化如何,我们可以在阵列做细粒度的观察,我们能够追踪插入,更新和删除?看来仅仅使用didSet观察者是无济于事的。任何想法如何完成?我碰到一个link 这似乎可以解释,我要找的东西,但它是有点复杂,难于理解。任何人都可以提供一个简单的例子来解决这个问题吗? 谢谢斯威夫特:阵列使用didSet

回答

1

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

“在didSet计算更改为时已晚”出于好奇,为什么你反对在didSet中使用“oldValue”魔术变量? – Charlesism

+1

不要把它放在背景之外。我并不反对,它适用于“财产设置之前”。 – hnh

0

可以概括如果您要在几个位置执行此操作,则可以使用扩展名中的检测以使其更易于管理:

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