public CFNotificationObserverToken AddObserver(string name, INativeObject objectToObserve, Action <string, NSDictionary> notificationHandler, CFNotificationSuspensionBehavior suspensionBehavior = CFNotificationSuspensionBehavior.DeliverImmediately) { if (darwinnc != null && darwinnc.Handle == Handle) { if (name == null) { throw new ArgumentNullException("name", "When using the Darwin Notification Center, the value passed must not be null"); } } var strHandle = name == null ? IntPtr.Zero : NSString.CreateNative(name); name = name ?? NullNotificationName; var token = new CFNotificationObserverToken() { stringName = name, centerHandle = handle, nameHandle = strHandle, observedObject = objectToObserve == null ? IntPtr.Zero : objectToObserve.Handle, listener = notificationHandler }; // // To allow callbacks to add observers, we duplicate the list of listeners on AddObserver // We do the duplication on AddObserver, instead of making a copy on the notification // callback, as we expect the notification callback to be a more common operation // than the AddObserver operation // List <CFNotificationObserverToken> listenersForName; lock (listeners){ if (!listeners.TryGetValue(name, out listenersForName)) { listenersForName = new List <CFNotificationObserverToken> (1); CFNotificationCenterAddObserver(center: handle, observer: handle, callback: NotificationCallback, name: strHandle, obj: token.observedObject, suspensionBehavior: (IntPtr)suspensionBehavior); } else { listenersForName = new List <CFNotificationObserverToken> (listenersForName); } listenersForName.Add(token); listeners [name] = listenersForName; } return(token); }
public void RemoveObserver(CFNotificationObserverToken token) { if (token == null) { throw new ArgumentNullException("token"); } if (token.nameHandle == IntPtr.Zero && token.stringName != NullNotificationName) { throw new ObjectDisposedException("token"); } if (token.centerHandle != handle) { throw new ArgumentException("token", "This token belongs to a different notification center"); } lock (listeners){ var list = listeners [token.stringName]; List <CFNotificationObserverToken> newList = null; foreach (var e in list) { if (e == token) { continue; } if (newList == null) { newList = new List <CFNotificationObserverToken> (); } newList.Add(e); } if (newList != null) { listeners [token.stringName] = newList; return; } else { listeners.Remove(token.stringName); } } CFNotificationCenterRemoveObserver(handle, this.Handle, name: token.nameHandle, obj: token.observedObject); NSString.ReleaseNative(token.nameHandle); token.nameHandle = IntPtr.Zero; }