diff --git a/Frameworks/Foundation/NSKVOSupport.mm b/Frameworks/Foundation/NSKVOSupport.mm index f33c38adcf..666737cee9 100644 --- a/Frameworks/Foundation/NSKVOSupport.mm +++ b/Frameworks/Foundation/NSKVOSupport.mm @@ -301,7 +301,7 @@ static void _addNestedObserversAndOptionallyDependents(_NSKVOKeyObserver* keyObs } // If restOfKeypath is non-nil, we have to chain on further observers. - if (keyObserver.restOfKeypath) { + if (keyObserver.restOfKeypath && !keyObserver.restOfKeypathObserver) { keyObserver.restOfKeypathObserver = _addKeypathObserver([object valueForKey:key], keyObserver.restOfKeypath, keypathObserver, keyObserver.affectedObservers); } @@ -552,9 +552,8 @@ static inline id _valueForPendingChangeAtIndexes( inline static void _dispatchWillChange(id notifyingObject, NSString* key, TFunc&& func) { _NSKVOObservationInfo* observationInfo = (__bridge _NSKVOObservationInfo*)[notifyingObject observationInfo]; for (_NSKVOKeyObserver* keyObserver in [observationInfo observersForKey:key]) { - _NSKVOKeypathObserver* keypathObserver = keyObserver.keypathObserver; - // Skip any keypaths that are in the process of changing. + _NSKVOKeypathObserver* keypathObserver = keyObserver.keypathObserver; if ([keypathObserver pushWillChange]) { // Call into the lambda function, which will do the actual set-up for pendingChanges func(keyObserver); @@ -569,10 +568,10 @@ inline static void _dispatchWillChange(id notifyingObject, NSString* key, TFunc& context:keypathObserver.context]; [change removeObjectForKey:NSKeyValueChangeNotificationIsPriorKey]; } - - // This must happen regardless of whether we are currently notifying. - _removeNestedObserversAndOptionallyDependents(keyObserver, false); } + + // This must happen regardless of whether we are currently notifying. + _removeNestedObserversAndOptionallyDependents(keyObserver, false); } }