i've created wrapper dictionary, i'd use didset property observer on instances of it. can didset private dictionary not sure how define within wrapper class.
i pass oldvalue swift dictionary well, here's class:
public class synchronizeddictionary<k: hashable,v> { private var dictionary: [k:v] = dictionary() { didset { } } private let accessqueue: dispatch_queue_t public var count: int { { 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 } } { var element: v? dispatch_sync(self.accessqueue) { element = self.dictionary[index] } return element } } /// removes value given key , key. public func removevalueforkey(key: k) { dispatch_barrier_async(self.accessqueue) { () -> void in if self.dictionary[key] != nil { self.dictionary.removevalueforkey(key) } } } /// returns dictionary values 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 } }
you use delegate: called property observer observing updates of private dictionary in synchronizeddictionary
, in turn triggering callback method in class work synchronizeddictionary
object. below follows example of procedure applied simplified version of custom dictionary class.
note property observer (i'm using willset
convenience) set tuple in turn used update private dictionary, rather trying observe changes in private dictionary (the latter make tricky make sense out of newvalue
in willset
property observer).
public protocol mydictionarydelegate { typealias mykey typealias myvalue func existingdictionaryentrywasupdated(oldvalue: myvalue, newpair: (mykey, myvalue)) } public class minimalsynchronizeddictionary<k: hashable, v: comparable, t: mydictionarydelegate t.mykey == k, t.myvalue == v> { private var updatedictionarywithpair : (k, v) { /* note, willset not called prior update in initializer, can use dummy pair begin with, ok */ willset { /* update existing dict. entry */ if let oldvalue = dictionary[newvalue.0] 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 } }
note i've type constrained generic v
protocol comparable
example (to make use of !=
operator in willset
clause), can leave out if don't plan on comparing dictionary values against each other.
now, example class conforming mydictionarydelegate
, containing minimalsynchronizeddictionary
object , receiving delegate callbacks objects delegate.
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 key '\(newpair.0)' updated old value '\(oldvalue)' 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 key 'world' updated old value '1' new value '2'. */ mymainclass.syncdict.updatedictionarywithpair(newpair: ("world", 2)) /* (key exists, same value --> no update) */ mymainclass.syncdict.updatedictionarywithpair(newpair: ("world", 3)) /* prints: dictionary entry key 'world' updated old value '2' new value '3'. */
Comments
Post a Comment