-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Take 2 of “[SDK] Fix multiple issues with Swift KVO” #22311
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -108,7 +108,72 @@ print("target removed") | |
// CHECK-NEXT: swiftValue 42, objcValue three | ||
// CHECK-NEXT: swiftValue 42, objcValue four | ||
// CHECK-NEXT: swiftValue 13, objcValue four | ||
// The next 2 logs are actually a bug and shouldn't happen | ||
// CHECK-NEXT: swiftValue 13, objcValue four | ||
// CHECK-NEXT: swiftValue 13, objcValue four | ||
// CHECK-NEXT: target removed | ||
|
||
//===----------------------------------------------------------------------===// | ||
// Test NSKeyValueObservingCustomization issue with observing from the callbacks | ||
//===----------------------------------------------------------------------===// | ||
|
||
class Target2 : NSObject, NSKeyValueObservingCustomization { | ||
@objc dynamic var name: String? | ||
|
||
class Dummy : NSObject { | ||
@objc dynamic var name: String? | ||
} | ||
|
||
// In both of the callbacks, observe another property with the same key path. | ||
// We do it in both because we're not sure which callback is invoked first. | ||
// This ensures that using KVO with key paths from one callback doesn't interfere | ||
// with the ability to look up the key path using the other. | ||
static func keyPathsAffectingValue(for key: AnyKeyPath) -> Set<AnyKeyPath> { | ||
print("keyPathsAffectingValue: key == \\.name:", key == \Target2.name) | ||
withExtendedLifetime(Dummy()) { (dummy) in | ||
_ = dummy.observe(\.name) { (_, _) in } | ||
} | ||
return [] | ||
} | ||
|
||
static func automaticallyNotifiesObservers(for key: AnyKeyPath) -> Bool { | ||
print("automaticallyNotifiesObservers: key == \\.name:", key == \Target2.name) | ||
withExtendedLifetime(Dummy()) { (dummy) in | ||
_ = dummy.observe(\.name) { (_, _) in } | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These 2 lines have hard tabs instead of spaces. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. … one day, humanity will solve the problem of varying configurations between hosts and contexts There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (I will wait for testing to end before adding a fix.) |
||
return true | ||
} | ||
} | ||
|
||
print("registering observer for Target2") | ||
withExtendedLifetime(Target2()) { (target) in | ||
_ = target.observe(\.name) { (_, _) in } | ||
} | ||
print("observer removed") | ||
|
||
// CHECK-LABEL: registering observer for Target2 | ||
// CHECK-DAG: keyPathsAffectingValue: key == \.name: true | ||
// CHECK-DAG: automaticallyNotifiesObservers: key == \.name: true | ||
// CHECK-NEXT: observer removed | ||
|
||
//===----------------------------------------------------------------------===// | ||
// Test NSSortDescriptor keyPath support | ||
//===----------------------------------------------------------------------===// | ||
|
||
// This one doesn't really match the context of "KVO KeyPaths" but it's close enough | ||
|
||
class Sortable1 : NSObject { | ||
@objc var name: String? | ||
} | ||
|
||
class Sortable2 : NSObject { | ||
@objc var name: String? | ||
} | ||
|
||
print("creating NSSortDescriptor") | ||
let descriptor = NSSortDescriptor(keyPath: \Sortable1.name, ascending: true) | ||
_ = NSSortDescriptor(keyPath: \Sortable2.name, ascending: true) | ||
print("keyPath == \\Sortable1.name:", descriptor.keyPath == \Sortable1.name) | ||
|
||
// CHECK-LABEL: creating NSSortDescriptor | ||
// CHECK-NEXT: keyPath == \Sortable1.name: true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These 2 lines have hard tabs instead of spaces.