NSKVOSupport: Retrieve the underlying class when adding nested observers

This commit is contained in:
Hugo Melder 2024-12-17 12:54:44 +01:00
parent 3f27cb0d23
commit 84e7734fdb
2 changed files with 27 additions and 1 deletions

View file

@ -123,6 +123,7 @@ _NSKVOEnsureKeyWillNotify(id object, NSString *key);
*/
@interface
NSObject (NSKeyValueObservingPrivate)
- (Class)_underlyingClass;
- (void)_notifyObserversOfChangeForKey:(NSString *)key
oldValue:(id)oldValue
newValue:(id)newValue;

View file

@ -333,7 +333,11 @@ _addNestedObserversAndOptionallyDependents(_NSKVOKeyObserver *keyObserver,
// Aggregate all keys whose values will affect us.
if (dependents)
{
Class cls = [object class];
// Make sure to retrieve the underlying class of the observee.
// This is just [object class] for an NSObject derived class.
// When observing an object through a proxy, we instead use KVC
// to optain the underlying class.
Class cls = [object _underlyingClass];
NSSet *valueInfluencingKeys = [cls keyPathsForValuesAffectingValueForKey: key];
if (valueInfluencingKeys.count > 0)
{
@ -1123,6 +1127,11 @@ static const NSString *_NSKeyValueChangeOldSetValue
@implementation
NSObject (NSKeyValueObservingPrivate)
- (Class)_underlyingClass
{
return [self class];
}
- (void)_notifyObserversOfChangeForKey: (NSString *)key
oldValue: (id)oldValue
newValue: (id)newValue
@ -1254,3 +1263,19 @@ NSSet (NSKeyValueObserving)
@end
#pragma endregion
#pragma region KVO forwarding - NSProxy category
@implementation
NSProxy (NSKeyValueObserving)
- (Class)_underlyingClass
{
// Retrieve the underlying class via KVC
// Note that we assume that the class is KVC-compliant, when KVO is used
return [(NSObject *)self valueForKey: @"class"];
}
@end
#pragma endregion