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