@@ -35,46 +35,49 @@ public protocol NSKeyValueObservingCustomization : NSObjectProtocol {
35
35
36
36
fileprivate extension NSObject {
37
37
38
- @objc class func _old_unswizzled_automaticallyNotifiesObservers ( forKey key: String ? ) -> Bool {
38
+ @objc class func __old_unswizzled_automaticallyNotifiesObservers ( forKey key: String ? ) -> Bool {
39
39
fatalError ( " Should never be reached " )
40
40
}
41
41
42
- @objc class func _old_unswizzled_keyPathsForValuesAffectingValue ( forKey key: String ? ) -> Set < String > {
42
+ @objc class func __old_unswizzled_keyPathsForValuesAffectingValue ( forKey key: String ? ) -> Set < String > {
43
43
fatalError ( " Should never be reached " )
44
44
}
45
45
46
46
}
47
47
48
- @objc private class _KVOKeyPathBridgeMachinery : NSObject {
48
+ // NOTE: older overlays called this _KVOKeyPathBridgeMachinery. The two
49
+ // must coexist, so it was renamed. The old name must not be used in the
50
+ // new runtime.
51
+ @objc private class __KVOKeyPathBridgeMachinery : NSObject {
49
52
@nonobjc static var keyPathTable : [ String : AnyKeyPath ] = {
50
53
/*
51
54
Move all our methods into place. We want the following:
52
- _KVOKeyPathBridgeMachinery 's automaticallyNotifiesObserversForKey:, and keyPathsForValuesAffectingValueForKey: methods replaces NSObject's versions of them
53
- NSObject's automaticallyNotifiesObserversForKey:, and keyPathsForValuesAffectingValueForKey: methods replace NSObject's _old_unswizzled_ * methods
54
- NSObject's _old_unswizzled_* methods replace _KVOKeyPathBridgeMachinery 's methods, and are never invoked
55
+ __KVOKeyPathBridgeMachinery 's automaticallyNotifiesObserversForKey:, and keyPathsForValuesAffectingValueForKey: methods replaces NSObject's versions of them
56
+ NSObject's automaticallyNotifiesObserversForKey:, and keyPathsForValuesAffectingValueForKey: methods replace NSObject's __old_unswizzled_ * methods
57
+ NSObject's _old_unswizzled_* methods replace __KVOKeyPathBridgeMachinery 's methods, and are never invoked
55
58
*/
56
59
let rootClass : AnyClass = NSObject . self
57
- let bridgeClass : AnyClass = _KVOKeyPathBridgeMachinery . self
60
+ let bridgeClass : AnyClass = __KVOKeyPathBridgeMachinery . self
58
61
59
62
let dependentSel = #selector( NSObject . keyPathsForValuesAffectingValue ( forKey: ) )
60
63
let rootDependentImpl = class_getClassMethod ( rootClass, dependentSel) !
61
64
let bridgeDependentImpl = class_getClassMethod ( bridgeClass, dependentSel) !
62
65
method_exchangeImplementations ( rootDependentImpl, bridgeDependentImpl) // NSObject <-> Us
63
66
64
67
let originalDependentImpl = class_getClassMethod ( bridgeClass, dependentSel) ! //we swizzled it onto this class, so this is actually NSObject's old implementation
65
- let originalDependentSel = #selector( NSObject . _old_unswizzled_keyPathsForValuesAffectingValue ( forKey: ) )
68
+ let originalDependentSel = #selector( NSObject . __old_unswizzled_keyPathsForValuesAffectingValue ( forKey: ) )
66
69
let dummyDependentImpl = class_getClassMethod ( rootClass, originalDependentSel) !
67
- method_exchangeImplementations ( originalDependentImpl, dummyDependentImpl) // NSObject's original version <-> NSObject's _old_unswizzled_ version
70
+ method_exchangeImplementations ( originalDependentImpl, dummyDependentImpl) // NSObject's original version <-> NSObject's __old_unswizzled_ version
68
71
69
72
let autoSel = #selector( NSObject . automaticallyNotifiesObservers ( forKey: ) )
70
73
let rootAutoImpl = class_getClassMethod ( rootClass, autoSel) !
71
74
let bridgeAutoImpl = class_getClassMethod ( bridgeClass, autoSel) !
72
75
method_exchangeImplementations ( rootAutoImpl, bridgeAutoImpl) // NSObject <-> Us
73
76
74
77
let originalAutoImpl = class_getClassMethod ( bridgeClass, autoSel) ! //we swizzled it onto this class, so this is actually NSObject's old implementation
75
- let originalAutoSel = #selector( NSObject . _old_unswizzled_automaticallyNotifiesObservers ( forKey: ) )
78
+ let originalAutoSel = #selector( NSObject . __old_unswizzled_automaticallyNotifiesObservers ( forKey: ) )
76
79
let dummyAutoImpl = class_getClassMethod ( rootClass, originalAutoSel) !
77
- method_exchangeImplementations ( originalAutoImpl, dummyAutoImpl) // NSObject's original version <-> NSObject's _old_unswizzled_ version
80
+ method_exchangeImplementations ( originalAutoImpl, dummyAutoImpl) // NSObject's original version <-> NSObject's __old_unswizzled_ version
78
81
79
82
return [ : ]
80
83
} ( )
@@ -83,62 +86,65 @@ fileprivate extension NSObject {
83
86
84
87
@nonobjc fileprivate static func _bridgeKeyPath( _ keyPath: __owned AnyKeyPath) -> String {
85
88
guard let keyPathString = keyPath. _kvcKeyPathString else { fatalError ( " Could not extract a String from KeyPath \( keyPath) " ) }
86
- _KVOKeyPathBridgeMachinery . keyPathTableLock. lock ( )
87
- defer { _KVOKeyPathBridgeMachinery . keyPathTableLock. unlock ( ) }
88
- _KVOKeyPathBridgeMachinery . keyPathTable [ keyPathString] = keyPath
89
+ __KVOKeyPathBridgeMachinery . keyPathTableLock. lock ( )
90
+ defer { __KVOKeyPathBridgeMachinery . keyPathTableLock. unlock ( ) }
91
+ __KVOKeyPathBridgeMachinery . keyPathTable [ keyPathString] = keyPath
89
92
return keyPathString
90
93
}
91
94
92
95
@nonobjc fileprivate static func _bridgeKeyPath( _ keyPath: String ? ) -> AnyKeyPath ? {
93
96
guard let keyPath = keyPath else { return nil }
94
- _KVOKeyPathBridgeMachinery . keyPathTableLock. lock ( )
95
- defer { _KVOKeyPathBridgeMachinery . keyPathTableLock. unlock ( ) }
96
- let path = _KVOKeyPathBridgeMachinery . keyPathTable [ keyPath]
97
+ __KVOKeyPathBridgeMachinery . keyPathTableLock. lock ( )
98
+ defer { __KVOKeyPathBridgeMachinery . keyPathTableLock. unlock ( ) }
99
+ let path = __KVOKeyPathBridgeMachinery . keyPathTable [ keyPath]
97
100
return path
98
101
}
99
102
100
103
@objc override class func automaticallyNotifiesObservers( forKey key: String ) -> Bool {
101
104
//This is swizzled so that it's -[NSObject automaticallyNotifiesObserversForKey:]
102
- if let customizingSelf = self as? NSKeyValueObservingCustomization . Type , let path = _KVOKeyPathBridgeMachinery . _bridgeKeyPath ( key) {
105
+ if let customizingSelf = self as? NSKeyValueObservingCustomization . Type , let path = __KVOKeyPathBridgeMachinery . _bridgeKeyPath ( key) {
103
106
return customizingSelf. automaticallyNotifiesObservers ( for: path)
104
107
} else {
105
- return self . _old_unswizzled_automaticallyNotifiesObservers ( forKey: key) //swizzled to be NSObject's original implementation
108
+ return self . __old_unswizzled_automaticallyNotifiesObservers ( forKey: key) //swizzled to be NSObject's original implementation
106
109
}
107
110
}
108
111
109
112
@objc override class func keyPathsForValuesAffectingValue( forKey key: String ? ) -> Set < String > {
110
113
//This is swizzled so that it's -[NSObject keyPathsForValuesAffectingValueForKey:]
111
- if let customizingSelf = self as? NSKeyValueObservingCustomization . Type , let path = _KVOKeyPathBridgeMachinery . _bridgeKeyPath ( key!) {
114
+ if let customizingSelf = self as? NSKeyValueObservingCustomization . Type , let path = __KVOKeyPathBridgeMachinery . _bridgeKeyPath ( key!) {
112
115
let resultSet = customizingSelf. keyPathsAffectingValue ( for: path)
113
116
return Set ( resultSet. lazy. map {
114
117
guard let str = $0. _kvcKeyPathString else { fatalError ( " Could not extract a String from KeyPath \( $0) " ) }
115
118
return str
116
119
} )
117
120
} else {
118
- return self . _old_unswizzled_keyPathsForValuesAffectingValue ( forKey: key) //swizzled to be NSObject's original implementation
121
+ return self . __old_unswizzled_keyPathsForValuesAffectingValue ( forKey: key) //swizzled to be NSObject's original implementation
119
122
}
120
123
}
121
124
}
122
125
123
126
func _bridgeKeyPathToString( _ keyPath: AnyKeyPath ) -> String {
124
- return _KVOKeyPathBridgeMachinery . _bridgeKeyPath ( keyPath)
127
+ return __KVOKeyPathBridgeMachinery . _bridgeKeyPath ( keyPath)
125
128
}
126
129
127
130
func _bridgeStringToKeyPath( _ keyPath: String ) -> AnyKeyPath ? {
128
- return _KVOKeyPathBridgeMachinery . _bridgeKeyPath ( keyPath)
131
+ return __KVOKeyPathBridgeMachinery . _bridgeKeyPath ( keyPath)
129
132
}
130
133
131
- public class NSKeyValueObservation : NSObject {
134
+ // NOTE: older overlays called this NSKeyValueObservation. The two must
135
+ // coexist, so it was renamed. The old name must not be used in the new
136
+ // runtime.
137
+ public class _NSKeyValueObservation : NSObject {
132
138
133
139
@nonobjc weak var object : NSObject ?
134
140
@nonobjc let callback : ( NSObject , NSKeyValueObservedChange < Any > ) -> Void
135
141
@nonobjc let path : String
136
142
137
143
//workaround for <rdar://problem/31640524> Erroneous (?) error when using bridging in the Foundation overlay
138
- @nonobjc static var swizzler : NSKeyValueObservation ? = {
139
- let bridgeClass : AnyClass = NSKeyValueObservation . self
144
+ @nonobjc static var swizzler : _NSKeyValueObservation ? = {
145
+ let bridgeClass : AnyClass = _NSKeyValueObservation . self
140
146
let observeSel = #selector( NSObject . observeValue ( forKeyPath: of: change: context: ) )
141
- let swapSel = #selector( NSKeyValueObservation . _swizzle_me_observeValue ( forKeyPath: of: change: context: ) )
147
+ let swapSel = #selector( _NSKeyValueObservation . _swizzle_me_observeValue ( forKeyPath: of: change: context: ) )
142
148
let rootObserveImpl = class_getInstanceMethod ( bridgeClass, observeSel)
143
149
let swapObserveImpl = class_getInstanceMethod ( bridgeClass, swapSel)
144
150
method_exchangeImplementations ( rootObserveImpl, swapObserveImpl)
@@ -147,7 +153,7 @@ public class NSKeyValueObservation : NSObject {
147
153
148
154
fileprivate init ( object: NSObject , keyPath: AnyKeyPath , callback: @escaping ( NSObject , NSKeyValueObservedChange < Any > ) -> Void ) {
149
155
path = _bridgeKeyPathToString ( keyPath)
150
- let _ = NSKeyValueObservation . swizzler
156
+ let _ = _NSKeyValueObservation . swizzler
151
157
self . object = object
152
158
self . callback = callback
153
159
}
@@ -156,7 +162,7 @@ public class NSKeyValueObservation : NSObject {
156
162
object? . addObserver ( self , forKeyPath: path, options: options, context: nil )
157
163
}
158
164
159
- ///invalidate() will be called automatically when an NSKeyValueObservation is deinited
165
+ ///invalidate() will be called automatically when an _NSKeyValueObservation is deinited
160
166
@objc public func invalidate( ) {
161
167
object? . removeObserver ( self , forKeyPath: path, context: nil )
162
168
object = nil
@@ -181,13 +187,13 @@ public class NSKeyValueObservation : NSObject {
181
187
182
188
extension _KeyValueCodingAndObserving {
183
189
184
- ///when the returned NSKeyValueObservation is deinited or invalidated, it will stop observing
190
+ ///when the returned _NSKeyValueObservation is deinited or invalidated, it will stop observing
185
191
public func observe< Value> (
186
192
_ keyPath: KeyPath < Self , Value > ,
187
193
options: NSKeyValueObservingOptions = [ ] ,
188
194
changeHandler: @escaping ( Self , NSKeyValueObservedChange < Value > ) -> Void )
189
- -> NSKeyValueObservation {
190
- let result = NSKeyValueObservation ( object: self as! NSObject , keyPath: keyPath) { ( obj, change) in
195
+ -> _NSKeyValueObservation {
196
+ let result = _NSKeyValueObservation ( object: self as! NSObject , keyPath: keyPath) { ( obj, change) in
191
197
let notification = NSKeyValueObservedChange ( kind: change. kind,
192
198
newValue: change. newValue as? Value ,
193
199
oldValue: change. oldValue as? Value ,
0 commit comments