From 3c837be72674f7103a251fcd8ef38ebaa099f3e0 Mon Sep 17 00:00:00 2001 From: p-x9 <50244599+p-x9@users.noreply.github.com> Date: Sat, 21 Jan 2023 23:26:45 +0900 Subject: [PATCH 1/2] Ignore the value of `object` if `darwinNotify`. --- Sources/SCFNotification/Extension/Array+.swift | 12 ++++++++++++ Sources/SCFNotification/Observation.swift | 13 ++++++++++--- Sources/SCFNotification/ObservationStore.swift | 2 +- Sources/SCFNotification/SCFNotificationCenter.swift | 6 +++++- 4 files changed, 28 insertions(+), 5 deletions(-) diff --git a/Sources/SCFNotification/Extension/Array+.swift b/Sources/SCFNotification/Extension/Array+.swift index 5932131..ba5bc2e 100644 --- a/Sources/SCFNotification/Extension/Array+.swift +++ b/Sources/SCFNotification/Extension/Array+.swift @@ -53,4 +53,16 @@ extension Array where Element == Observation { $0.observer != nil } } + + func notifyNeededOnly(observer: UnsafeMutableRawPointer?, object: UnsafeRawPointer?) -> Array { + filter { + guard observer == $0.observerPtr else { + return false + } + if let objectPtr = $0.objectPtr { + return object == objectPtr + } + return true + } + } } diff --git a/Sources/SCFNotification/Observation.swift b/Sources/SCFNotification/Observation.swift index 38a0935..a61127c 100644 --- a/Sources/SCFNotification/Observation.swift +++ b/Sources/SCFNotification/Observation.swift @@ -20,11 +20,17 @@ struct Observation { weak var object: AnyObject? var observerPtr: UnsafeMutableRawPointer? { - unsafeBitCast(observer, to: UnsafeMutableRawPointer?.self) + guard let observer = self.observer else { + return nil + } + return unsafeBitCast(observer, to: UnsafeMutableRawPointer?.self) } var objectPtr: UnsafeRawPointer? { - unsafeBitCast(object, to: UnsafeRawPointer?.self) + guard let object = self.object else { + return nil + } + return unsafeBitCast(object, to: UnsafeRawPointer?.self) } let notify: SCFNotificationCallbackObjC @@ -40,7 +46,8 @@ struct Observation { observer = unsafeBitCast(observerPtr, to: Observer?.self) } var object: Object? - if let objectPtr { + if let objectPtr, + center?.centerType != .darwinNotify { object = unsafeBitCast(objectPtr, to: Object?.self) } notify?(center, observer, name, object, userInfo) diff --git a/Sources/SCFNotification/ObservationStore.swift b/Sources/SCFNotification/ObservationStore.swift index 2a9b084..99d87c5 100644 --- a/Sources/SCFNotification/ObservationStore.swift +++ b/Sources/SCFNotification/ObservationStore.swift @@ -93,7 +93,7 @@ class ObservationStore { } observations - .filterWith(observer: observer, object: object) + .notifyNeededOnly(observer: observer, object: object) .forEach { $0.notify(center.cfNotificationCenter, observer, name, object, userInfo) } diff --git a/Sources/SCFNotification/SCFNotificationCenter.swift b/Sources/SCFNotification/SCFNotificationCenter.swift index 8b33465..25f0f45 100644 --- a/Sources/SCFNotification/SCFNotificationCenter.swift +++ b/Sources/SCFNotification/SCFNotificationCenter.swift @@ -65,11 +65,15 @@ extension SCFNotificationCenter { suspensionBehavior: CFNotificationSuspensionBehavior, callback: @escaping SCFNotificationCallback) { - let observation = Observation(name: name.rawValue, + var observation = Observation(name: name.rawValue, observer: observer, object: object, notify: callback) + if center == .darwinNotify { + observation.object = nil + } + ObservationStore.shared.add(observation, center: center) CFNotificationCenterAddObserver(center.cfNotificationCenter, observation.observerPtr, { center, observer, name, object, userInfo in From 07bd3ffc0766ae2c5f1b53a0a51a7223fcbc53b0 Mon Sep 17 00:00:00 2001 From: p-x9 <50244599+p-x9@users.noreply.github.com> Date: Sun, 22 Jan 2023 01:29:00 +0900 Subject: [PATCH 2/2] limit observer and object types to class types --- Sources/SCFNotification/Observation.swift | 4 +- .../SCFNotificationCenter.swift | 48 +++++++++---------- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/Sources/SCFNotification/Observation.swift b/Sources/SCFNotification/Observation.swift index a61127c..7e053bc 100644 --- a/Sources/SCFNotification/Observation.swift +++ b/Sources/SCFNotification/Observation.swift @@ -34,8 +34,8 @@ struct Observation { } let notify: SCFNotificationCallbackObjC - - init(name: CFString, observer: Observer, object: Object?, notify: SCFNotificationCallback?) { + + init(name: CFString, observer: Observer, object: Object?, notify: SCFNotificationCallback?) { self.name = name as CFString self.observer = observer as AnyObject? self.object = object as AnyObject? diff --git a/Sources/SCFNotification/SCFNotificationCenter.swift b/Sources/SCFNotification/SCFNotificationCenter.swift index 25f0f45..9801a39 100644 --- a/Sources/SCFNotification/SCFNotificationCenter.swift +++ b/Sources/SCFNotification/SCFNotificationCenter.swift @@ -1,6 +1,6 @@ import Foundation -public typealias SCFNotificationCallback = (CFNotificationCenter?, Observer?, CFNotificationName?, Object?, CFDictionary?) -> Void +public typealias SCFNotificationCallback = (CFNotificationCenter?, Observer?, CFNotificationName?, Object?, CFDictionary?) -> Void public class SCFNotificationCenter { @@ -17,11 +17,11 @@ public class SCFNotificationCenter { self.center = center } - public func addObserver(observer: Observer, - name: CFNotificationName, - object: Any? = nil, - suspensionBehavior: CFNotificationSuspensionBehavior, - callback: @escaping SCFNotificationCallback) { + public func addObserver(observer: Observer, + name: CFNotificationName, + object: AnyObject? = nil, + suspensionBehavior: CFNotificationSuspensionBehavior, + callback: @escaping SCFNotificationCallback) { Self.addObserver(center: center, observer: observer, name: name, @@ -30,22 +30,22 @@ public class SCFNotificationCenter { callback: callback) } - public func removeObserver(observer: Observer, - name: CFNotificationName, - object: Any? = nil) { + public func removeObserver(observer: Observer, + name: CFNotificationName, + object: AnyObject? = nil) { Self.removeObserver(center: center, observer: observer, name: name, object: object) } - public func removeEveryObserver(observer: Observer) { + public func removeEveryObserver(observer: Observer) { Self.removeEveryObserver(center: center, observer: observer) } public func postNotification(name: CFNotificationName?, - object: Any? = nil, + object: AnyObject? = nil, userInfo: CFDictionary, deliverImmediately: Bool) { Self.postNotification(center: center, @@ -58,12 +58,12 @@ public class SCFNotificationCenter { extension SCFNotificationCenter { - public static func addObserver(center: CenterType, - observer: Observer, - name: CFNotificationName, - object: Any? = nil, - suspensionBehavior: CFNotificationSuspensionBehavior, - callback: @escaping SCFNotificationCallback) { + public static func addObserver(center: CenterType, + observer: Observer, + name: CFNotificationName, + object: AnyObject? = nil, + suspensionBehavior: CFNotificationSuspensionBehavior, + callback: @escaping SCFNotificationCallback) { var observation = Observation(name: name.rawValue, observer: observer, @@ -87,10 +87,10 @@ extension SCFNotificationCenter { }, observation.name, observation.objectPtr, suspensionBehavior) } - public static func removeObserver(center: CenterType, - observer: Observer, - name: CFNotificationName, - object: Any? = nil) { + public static func removeObserver(center: CenterType, + observer: Observer, + name: CFNotificationName, + object: AnyObject? = nil) { let observer = unsafeBitCast(observer, to: UnsafeMutableRawPointer.self) var objectPtr: UnsafeRawPointer? @@ -103,8 +103,8 @@ extension SCFNotificationCenter { CFNotificationCenterRemoveObserver(center.cfNotificationCenter, observer, name, objectPtr) } - public static func removeEveryObserver(center: CenterType, - observer: Observer) { + public static func removeEveryObserver(center: CenterType, + observer: Observer) { let observer = unsafeBitCast(observer, to: UnsafeMutableRawPointer.self) ObservationStore.shared.removeEvery(center: center, observer: observer) @@ -113,7 +113,7 @@ extension SCFNotificationCenter { public static func postNotification(center: CenterType, name: CFNotificationName?, - object: Any? = nil, + object: AnyObject? = nil, userInfo: CFDictionary, deliverImmediately: Bool) { var objectPtr: UnsafeRawPointer?