Merge pull request #323 from gnustep/NSKeyValueObserving_issue322

This commit is contained in:
Gregory Casamento 2023-09-18 12:29:26 -04:00 committed by GitHub
commit d97c84b9ed
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 68 additions and 0 deletions

View file

@ -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)

View file

@ -1288,6 +1288,43 @@ cifframe_callback(ffi_cif *cif, void *retp, void **args, void *user)
[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
@ -1561,6 +1598,32 @@ cifframe_callback(ffi_cif *cif, void *retp, void **args, void *user)
[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
/**