Swift 泛型类的属性观察器

Swift 泛型类的属性观察器,swift,Swift,我已经为字典创建了一个包装器,我想在它的实例上使用didSet属性observer。我可以从私有字典中获取didSet,但不确定如何在包装器类中定义它 我还想传递Swift字典中的oldValue,下面是类: public class SynchronizedDictionary<K: Hashable,V> { private var dictionary: [K:V] = Dictionary() { didSet { } } private let accessQueue:

我已经为字典创建了一个包装器,我想在它的实例上使用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

}

}
公共类同步字典{
私有变量字典:[K:V]=dictionary(){didSet{}
私有let访问队列:调度队列
公共变量计数:Int{
得到{
变量计数:Int!
dispatch_sync(self.accessQueue){()->Void in
count=self.dictionary.count
}
返回计数
}
}
init(){
让qosClassUserInit=QOS\u类\u用户\u启动
让newConcurrentQueueAttributes=dispatch_queue_attr_make_与qos_类(dispatch_queue_CONCURRENT,qosClassUserInit,0)
让newConcurrentQueue=dispatch\u queue\u create(“SynchronizedDictionaryAccess”,newConcurrentQueueAttributes)
self.accessQueue=newConcurrentQueue
}
公共下标(索引:K)->V{
设置{
dispatch\u barrier\u async(self.accessQueue){
self.dictionary[index]=newValue
}
}
得到{
var元素:V?
调度同步(self.accessQueue){
元素=self.dictionary[索引]
}
返回元素
}
}
///删除给定键和键的值。
公共函数移除值forkey(键:K){
dispatch\u barrier\u async(self.accessQueue){()->Void in
如果self.dictionary[key]!=nil{
self.dictionary.removeValueForKey(键)
}
}
}
///以数组形式返回字典值。
公共函数值()->[V]{
变量值=[V]()
dispatch_sync(self.accessQueue){()->Void in
值=数组(self.dictionary.values)
}
返回值
}
公共职能removeAll(){
dispatch\u barrier\u async(self.accessQueue){()->Void in
self.dictionary.removeAll()
}
}
public func doesObjectExistsForKey(键:K)->Bool{
var值:V?
dispatch_sync(self.accessQueue){()->Void in
value=self.dictionary[key]
}
返回值!=nil?真:假
}
}

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

请注意,属性观察器(为了方便起见,我正在使用
willSet
)被设置为一个元组,该元组反过来用于更新私有字典,而不是试图观察私有字典本身的更改(后者会使
willSet
属性观察器中的
newValue
难以理解)


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

请注意,属性观察器(为了方便起见,我正在使用
willSet
)被设置为一个元组,该元组反过来用于更新私有字典,而不是试图观察私有字典本身的更改(后者会使
willSet
属性观察器中的
newValue
难以理解)


didSet
属性观察器仅适用于具有
SynchronizedDictionary
类型属性的其他类。您希望通过
didSet
实现什么?我需要使用字典中添加或删除的值更新数组。您可以使用委托;从pr调用在类中的实际字典上的属性观察者,触发对处理数组的类中的某个函数的回调。更多信息:我有一个实例在另一个实例(创建它的实例)上更新此字典,创建它的那一个还必须管理一个字典值数组。我可以添加方法来处理这个问题,但有兴趣使用属性观察器。@dfri委托可能很好。
didSet
属性观察器仅适用于具有
SynchronizedDictionary
类型属性的其他类。您希望通过
didSet
实现什么?我需要使用添加到字典或从字典中删除的值更新数组。您可以使用委托;从类中实际字典的属性观察器调用,触发对使用数组的类中某个函数的回调。a更多信息:我有一个实例在另一个实例(创建字典的那个实例)上更新字典,创建它的那个人还必须管理一个字典值数组。我可以添加方法来处理这个问题,但我对使用属性观察器感兴趣。@dfri委托可能很好。我想这会解决的,我需要一些时间来把它全部放在一起,但它看起来不错。@thefreelement很乐意提供帮助,希望它可以为你工作。我想这会成功的,我需要一些时间来把它整理好,但它看起来不错。@ThefreedElement很乐意帮忙,希望它能为你工作。
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
    }
}
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'.         */