@@ -83,85 +83,56 @@ open class NSNotification: NSObject, NSCopying, NSCoding {
83
83
}
84
84
85
85
private class NSNotificationReceiver : NSObject {
86
- fileprivate weak var object : NSObject ?
87
86
fileprivate var name : Notification . Name ?
88
87
fileprivate var block : ( ( Notification ) -> Void ) ?
89
88
fileprivate var sender : AnyObject ?
90
89
fileprivate var queue : OperationQueue ?
91
90
}
92
91
93
- extension Sequence where Iterator. Element : NSNotificationReceiver {
94
-
95
- /// Returns collection of `NSNotificationReceiver`.
96
- ///
97
- /// Will return:
98
- /// - elements that property `object` is not equal to `observerToFilter`
99
- /// - elements that property `name` is not equal to parameter `name` if specified.
100
- /// - elements that property `sender` is not equal to parameter `object` if specified.
101
- ///
102
- fileprivate func filterOutObserver( _ observerToFilter: AnyObject , name: Notification . Name ? = nil , object: Any ? = nil ) -> [ Iterator . Element ] {
103
- return self . filter { observer in
104
-
105
- let differentObserver = observer. object !== observerToFilter
106
- let nameSpecified = name != nil
107
- let differentName = observer. name != name
108
- let objectSpecified = object != nil
109
- let differentSender = observer. sender !== __SwiftValue. store ( object)
110
-
111
- return differentObserver || ( nameSpecified && differentName) || ( objectSpecified && differentSender)
112
- }
113
- }
114
-
115
- /// Returns collection of `NSNotificationReceiver`.
116
- ///
117
- /// Will return:
118
- /// - elements that property `sender` is `nil` or equals specified parameter `sender`.
119
- /// - elements that property `name` is `nil` or equals specified parameter `name`.
120
- ///
121
- fileprivate func observersMatchingName( _ name: Notification . Name ? = nil , sender: Any ? = nil ) -> [ Iterator . Element ] {
122
- return self . filter { observer in
123
-
124
- let emptyName = observer. name == nil
125
- let sameName = observer. name == name
126
- let emptySender = observer. sender == nil
127
- let sameSender = observer. sender === __SwiftValue. store ( sender)
128
-
129
- return ( emptySender || sameSender) && ( emptyName || sameName)
130
- }
131
- }
132
- }
133
-
134
92
private let _defaultCenter : NotificationCenter = NotificationCenter ( )
135
93
136
94
open class NotificationCenter : NSObject {
95
+ private lazy var _nilIdentifier : ObjectIdentifier = ObjectIdentifier ( _observersLock)
96
+ private lazy var _nilHashable : AnyHashable = AnyHashable ( _nilIdentifier)
137
97
138
- private var _observers : [ NSNotificationReceiver ]
98
+ private var _observers : [ AnyHashable /* Notification.Name */ : [ ObjectIdentifier /* object */ : [ ObjectIdentifier /* notification receiver */ : NSNotificationReceiver ] ] ]
139
99
private let _observersLock = NSLock ( )
140
100
141
101
public required override init ( ) {
142
- _observers = [ NSNotificationReceiver] ( )
102
+ _observers = [ AnyHashable : [ ObjectIdentifier : [ ObjectIdentifier : NSNotificationReceiver] ] ] ( )
143
103
}
144
104
145
105
open class var `default` : NotificationCenter {
146
106
return _defaultCenter
147
107
}
148
108
149
109
open func post( _ notification: Notification ) {
110
+ let notificationNameIdentifier : AnyHashable = AnyHashable ( notification. name)
111
+ let senderIdentifier : ObjectIdentifier ? = notification. object. map ( { ObjectIdentifier ( __SwiftValue. store ( $0) ) } )
112
+
150
113
151
- let sendTo = _observersLock. synchronized ( {
152
- return _observers. observersMatchingName ( notification. name, sender: notification. object)
114
+ let sendTo : [ Dictionary < ObjectIdentifier , NSNotificationReceiver > . Values ] = _observersLock. synchronized ( {
115
+ var retVal = [ Dictionary < ObjectIdentifier , NSNotificationReceiver > . Values] ( )
116
+ ( _observers [ _nilHashable] ? [ _nilIdentifier] ? . values) . map ( { retVal. append ( $0) } )
117
+ senderIdentifier. flatMap ( { _observers [ _nilHashable] ? [ $0] ? . values } ) . map ( { retVal. append ( $0) } )
118
+ ( _observers [ notificationNameIdentifier] ? [ _nilIdentifier] ? . values) . map ( { retVal. append ( $0) } )
119
+ senderIdentifier. flatMap ( { _observers [ notificationNameIdentifier] ? [ $0] ? . values} ) . map ( { retVal. append ( $0) } )
120
+
121
+ return retVal
153
122
} )
154
123
155
- for observer in sendTo {
156
- guard let block = observer. block else {
157
- continue
158
- }
159
-
160
- if let queue = observer. queue, queue != OperationQueue . current {
161
- queue. addOperation { block ( notification) }
162
- queue. waitUntilAllOperationsAreFinished ( )
163
- } else {
164
- block ( notification)
124
+ sendTo. forEach { observers in
125
+ observers. forEach { observer in
126
+ guard let block = observer. block else {
127
+ return
128
+ }
129
+
130
+ if let queue = observer. queue, queue != OperationQueue . current {
131
+ queue. addOperation { block ( notification) }
132
+ queue. waitUntilAllOperationsAreFinished ( )
133
+ } else {
134
+ block ( notification)
135
+ }
165
136
}
166
137
}
167
138
}
@@ -176,12 +147,23 @@ open class NotificationCenter: NSObject {
176
147
}
177
148
178
149
open func removeObserver( _ observer: Any , name aName: NSNotification . Name ? , object: Any ? ) {
179
- guard let observer = observer as? NSObject else {
150
+ guard let observer = observer as? NSNotificationReceiver ,
151
+ // These 2 parameters would only be useful for removing notifications added by `addObserver:selector:name:object:`
152
+ aName == nil || observer. name == aName,
153
+ object == nil || observer. sender === __SwiftValue. store ( object)
154
+ else {
180
155
return
181
156
}
182
157
158
+ let notificationNameIdentifier : AnyHashable = observer. name. map { AnyHashable ( $0) } ?? _nilHashable
159
+ let senderIdentifier : ObjectIdentifier = observer. sender. map { ObjectIdentifier ( $0) } ?? _nilIdentifier
160
+ let receiverIdentifier : ObjectIdentifier = ObjectIdentifier ( observer)
161
+
183
162
_observersLock. synchronized ( {
184
- self . _observers = _observers. filterOutObserver ( observer, name: aName, object: object)
163
+ _observers [ notificationNameIdentifier] ? [ senderIdentifier] ? . removeValue ( forKey: receiverIdentifier)
164
+ if _observers [ notificationNameIdentifier] ? [ senderIdentifier] ? . count == 0 {
165
+ _observers [ notificationNameIdentifier] ? . removeValue ( forKey: senderIdentifier)
166
+ }
185
167
} )
186
168
}
187
169
@@ -191,20 +173,21 @@ open class NotificationCenter: NSObject {
191
173
}
192
174
193
175
open func addObserver( forName name: NSNotification . Name ? , object obj: Any ? , queue: OperationQueue ? , using block: @escaping ( Notification ) -> Void ) -> NSObjectProtocol {
194
- let object = NSObject ( )
195
-
196
176
let newObserver = NSNotificationReceiver ( )
197
- newObserver. object = object
198
177
newObserver. name = name
199
178
newObserver. block = block
200
179
newObserver. sender = __SwiftValue. store ( obj)
201
180
newObserver. queue = queue
181
+
182
+ let notificationNameIdentifier : AnyHashable = name. map ( { AnyHashable ( $0) } ) ?? _nilHashable
183
+ let senderIdentifier : ObjectIdentifier = newObserver. sender. map ( { ObjectIdentifier ( $0) } ) ?? _nilIdentifier
184
+ let receiverIdentifier : ObjectIdentifier = ObjectIdentifier ( newObserver)
202
185
203
186
_observersLock. synchronized ( {
204
- _observers. append ( newObserver)
187
+ _observers [ notificationNameIdentifier , default : [ : ] ] [ senderIdentifier , default : [ : ] ] [ receiverIdentifier ] = newObserver
205
188
} )
206
189
207
- return object
190
+ return newObserver
208
191
}
209
192
210
193
}
0 commit comments