泛型类的属性观察者

时间:2016-01-24 21:15:31

标签: swift

我已经为字典创建了一个包装器,我想在它的实例上使用didSet属性observer。我可以从私人字典中获取didSet但不确定如何在包装类中定义它。

我想从Swift字典中传递oldValue,这是类:

public class SynchronizedDictionary<K: Hashable,V> {

private var dictionary: [K:V] = Dictionary() { didSet {  } }
private let accessQueue: dispatch_queue_t
public var count: Int {

    get {

        var count: Int!
        dispatch_sync(self.accessQueue) { () -> Void in

            count = self.dictionary.count
        }

        return count
    }

}

init() {

    let qosClassUserInit                = QOS_CLASS_USER_INITIATED
    let newConcurrentQueueAttributes    = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_CONCURRENT, qosClassUserInit, 0)
    let newConcurrentQueue              = dispatch_queue_create("SynchronizedDictionaryAccess", newConcurrentQueueAttributes)
    self.accessQueue = newConcurrentQueue

}

public subscript(index: K) -> V? {

    set {

        dispatch_barrier_async(self.accessQueue) {

            self.dictionary[index] = newValue
        }

    }

    get {

        var element: V?
        dispatch_sync(self.accessQueue) {

            element = self.dictionary[index]
        }

        return element
    }

}

/// Removes the value for the given key and the key.
public func removeValueForKey(key: K) {

    dispatch_barrier_async(self.accessQueue) { () -> Void in

        if self.dictionary[key] != nil {

            self.dictionary.removeValueForKey(key)
        }

    }

}

/// Returns the dictionary values as an array.
public func values() -> [V] {

    var values = [V]()

    dispatch_sync(self.accessQueue) { () -> Void in

        values = Array(self.dictionary.values)
    }

    return values
}

public func removeAll() {

    dispatch_barrier_async(self.accessQueue) { () -> Void in

        self.dictionary.removeAll()
    }

}

public func doesObjectExistsForKey(key: K) -> Bool {

    var value: V?
    dispatch_sync(self.accessQueue) { () -> Void in

        value = self.dictionary[key]
    }

    return value != nil ? true : false

}

}

1 个答案:

答案 0 :(得分:2)

您可以使用委托:从属性观察者调用SynchronizedDictionary中的私有字典的更新,然后触发对使用SynchronizedDictionary对象的类中的某个方法的回调。下面是应用于自定义词典类的简化版本的此过程的示例。

请注意,属性观察者(为方便起见,我使用willSet)设置为元组,而元组又用于更新私有字典,而不是尝试观察私有字典本身的变化(后者会使newValue属性观察者willSet中的public protocol MyDictionaryDelegate { typealias MyKey typealias MyValue func existingDictionaryEntryWasUpdated(oldValue: MyValue, newPair: (MyKey, MyValue)) } public class MinimalSynchronizedDictionary<K: Hashable, V: Comparable, T: MyDictionaryDelegate where T.MyKey == K, T.MyValue == V> { private var updateDictionaryWithPair : (K, V) { /* Note, willSet not called prior to update in initializer, so we can use a dummy pair to begin with, OK */ willSet { /* update existing dict. entry */ if let oldValue = dictionary[newValue.0] where oldValue != newValue.1 { dictionary.updateValue(newValue.1, forKey: newValue.0) delegate?.existingDictionaryEntryWasUpdated(oldValue, newPair: newValue) } /* new dict. entry or same value update */ else { dictionary.updateValue(newValue.1, forKey: newValue.0) } } } private var dictionary: [K:V] = Dictionary() var delegate: T? init(dummyInitialDictPair: (K, V)) { updateDictionaryWithPair = dummyInitialDictPair } internal func updateDictionaryWithPair(newPair newPair: (K, V)) { updateDictionaryWithPair = newPair } } 理解变得棘手。

V

请注意,我为此示例键入了约束Comparable到协议!=(以便在willSet子句中使用MyDictionaryDelegate运算符),如果你不打算将字典值相互比较,你可以省略。

现在,示例类符合MinimalSynchronizedDictionary,包含class MyOtherClass : MyDictionaryDelegate { typealias MyKey = String typealias MyValue = Int var syncDict : MinimalSynchronizedDictionary<MyKey, MyValue, MyOtherClass> init(syncDict: MinimalSynchronizedDictionary<MyKey, MyValue, MyOtherClass>) { self.syncDict = syncDict self.syncDict.delegate = self } // MARK: MyDictionaryDelegate func existingDictionaryEntryWasUpdated(oldValue: MyValue, newPair: (MyKey, MyValue)) { print("Dictionary entry for key '\(newPair.0)' was updated from old value '\(oldValue)' to new value '\(newPair.1)'.") } } let myDict = MinimalSynchronizedDictionary<String, Int, MyOtherClass>(dummyInitialDictPair: ("",0)) let myMainClass = MyOtherClass(syncDict: myDict) myDict.updateDictionaryWithPair(newPair: ("World", 1)) myDict.updateDictionaryWithPair(newPair: ("Hello", 1)) myDict.updateDictionaryWithPair(newPair: ("World", 2)) /* Prints: Dictionary entry for key 'World' was updated from old value '1' to new value '2'. */ myMainClass.syncDict.updateDictionaryWithPair(newPair: ("World", 2)) /* (key exists, but same value --> no update) */ myMainClass.syncDict.updateDictionaryWithPair(newPair: ("World", 3)) /* Prints: Dictionary entry for key 'World' was updated from old value '2' to new value '3'. */ 对象,并从对象委托接收委托回调。

{{1}}