Skip to content

Commit

Permalink
Merge pull request #323 from gnustep/NSKeyValueObserving_issue322
Browse files Browse the repository at this point in the history
  • Loading branch information
gcasa committed Sep 18, 2023
2 parents dbebf76 + f73efa4 commit d97c84b
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 0 deletions.
5 changes: 5 additions & 0 deletions Headers/Foundation/NSKeyValueObserving.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,11 @@ GS_EXPORT NSString *const NSKeyValueChangeNotificationIsPriorKey;
- (void) removeObserver: (NSObject*)anObserver
forKeyPath: (NSString*)aPath;

#if OS_API_VERSION(MAC_OS_X_VERSION_10_7,GS_API_LATEST)
- (void) removeObserver: (NSObject*)anObserver
forKeyPath: (NSString*)aPath
context: (void *)context;
#endif
@end

@interface NSArray (NSKeyValueObserverRegistration)
Expand Down
63 changes: 63 additions & 0 deletions Source/NSKeyValueObserving.m
Original file line number Diff line number Diff line change
Expand Up @@ -1288,6 +1288,43 @@ - (void*) contextForObserver: (NSObject*)anObserver ofKeyPath: (NSString*)aPath
[iLock unlock];
return context;
}

- (void) removeObserver: (NSObject*)anObserver
forKeyPath: (NSString*)aPath
context: (void*)context
{
GSKVOPathInfo *pathInfo;

[iLock lock];
pathInfo = (GSKVOPathInfo*)NSMapGet(paths, (void*)aPath);
if (pathInfo != nil)
{
unsigned count = [pathInfo->observations count];

pathInfo->allOptions = 0;
while (count-- > 0)
{
GSKVOObservation *o;

o = [pathInfo->observations objectAtIndex: count];
if ((o->observer == anObserver || o->observer == nil) &&
(o->context == context))
{
[pathInfo->observations removeObjectAtIndex: count];
if ([pathInfo->observations count] == 0)
{
NSMapRemove(paths, (void*)aPath);
}
}
else
{
pathInfo->allOptions |= o->options;
}
}
}
[iLock unlock];
}

@end

@implementation NSKeyValueObservationForwarder
Expand Down Expand Up @@ -1561,6 +1598,32 @@ - (void) removeObserver: (NSObject*)anObserver forKeyPath: (NSString*)aPath
[forwarder finalize];
}

- (void) removeObserver: (NSObject*)anObserver
forKeyPath: (NSString*)aPath
context: (void *)context
{
GSKVOInfo *info;

setup();
[kvoLock lock];
/*
* Get the observation information and remove this observation.
*/
info = (GSKVOInfo*)[self observationInfo];
[info removeObserver: anObserver forKeyPath: aPath context: context];
if ([info isUnobserved] == YES)
{
/*
* The instance is no longer being observed ... so we can
* turn off key-value-observing for it.
*/
object_setClass(self, [self class]);
IF_NO_GC(AUTORELEASE(info);)
[self setObservationInfo: nil];
}
[kvoLock unlock];
}

@end

/**
Expand Down

0 comments on commit d97c84b

Please sign in to comment.