swift - Property observer for generic class -


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