From 2c81d3e003efd5b7bdd1428d2dfe73b4230c77f5 Mon Sep 17 00:00:00 2001 From: Gregory John Casamento Date: Wed, 13 Sep 2023 12:49:01 -0400 Subject: [PATCH 1/9] Add removeObserver:forKeyPath:context: to implementation --- Headers/Foundation/NSKeyValueObserving.h | 4 ++++ Source/NSKeyValueObserving.m | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/Headers/Foundation/NSKeyValueObserving.h b/Headers/Foundation/NSKeyValueObserving.h index e3568f106..8b1f4522c 100644 --- a/Headers/Foundation/NSKeyValueObserving.h +++ b/Headers/Foundation/NSKeyValueObserving.h @@ -138,6 +138,10 @@ GS_EXPORT NSString *const NSKeyValueChangeNotificationIsPriorKey; - (void) removeObserver: (NSObject*)anObserver forKeyPath: (NSString*)aPath; +- (void) removeObserver: (NSObject*)anObserver + forKeyPath: (NSString*)aPath + context: (void*)context; + @end @interface NSArray (NSKeyValueObserverRegistration) diff --git a/Source/NSKeyValueObserving.m b/Source/NSKeyValueObserving.m index 7cf27a3db..4836e2433 100644 --- a/Source/NSKeyValueObserving.m +++ b/Source/NSKeyValueObserving.m @@ -1561,6 +1561,12 @@ cifframe_callback(ffi_cif *cif, void *retp, void **args, void *user) [forwarder finalize]; } + +- (void) removeObserver: (NSObject*)anObserver forKeyPath: (NSString*)aPath context: (void*)context +{ + [self removeObserver: anObserver forKeyPath: aPath]; +} + @end /** From 5507ea1d1eacdb27aea60db8a7f6e9834c33f64b Mon Sep 17 00:00:00 2001 From: Gregory John Casamento Date: Thu, 14 Sep 2023 09:31:57 -0400 Subject: [PATCH 2/9] Change formatting --- Source/NSKeyValueObserving.m | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Source/NSKeyValueObserving.m b/Source/NSKeyValueObserving.m index 4836e2433..47fb3a38c 100644 --- a/Source/NSKeyValueObserving.m +++ b/Source/NSKeyValueObserving.m @@ -1562,7 +1562,9 @@ cifframe_callback(ffi_cif *cif, void *retp, void **args, void *user) } -- (void) removeObserver: (NSObject*)anObserver forKeyPath: (NSString*)aPath context: (void*)context +- (void) removeObserver: (NSObject*)anObserver + forKeyPath: (NSString*)aPath + context: (void*)context { [self removeObserver: anObserver forKeyPath: aPath]; } From b8bc924cdb394bf0a196161465cc3dd72601b032 Mon Sep 17 00:00:00 2001 From: Gregory John Casamento Date: Thu, 14 Sep 2023 12:22:56 -0400 Subject: [PATCH 3/9] Throw an exception when calling the removeObserver:forKeyPath:context: method --- Source/NSKeyValueObserving.m | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Source/NSKeyValueObserving.m b/Source/NSKeyValueObserving.m index 47fb3a38c..727b47fd2 100644 --- a/Source/NSKeyValueObserving.m +++ b/Source/NSKeyValueObserving.m @@ -1566,7 +1566,9 @@ cifframe_callback(ffi_cif *cif, void *retp, void **args, void *user) forKeyPath: (NSString*)aPath context: (void*)context { - [self removeObserver: anObserver forKeyPath: aPath]; + [NSException raise: NSGenericException + format: @"[%@-%@]: This class is not observable", + NSStringFromClass([self class]), NSStringFromSelector(_cmd)]; } @end From 0f3bb3d2b89b18c5e60e63a504ce3de6f7beff03 Mon Sep 17 00:00:00 2001 From: Gregory Casamento Date: Fri, 15 Sep 2023 14:13:44 -0400 Subject: [PATCH 4/9] Use keysight implementation of the method removeObjserver:forKeyPath:context: --- Headers/Foundation/NSKeyValueObserving.h | 7 ++--- Source/NSKeyValueObserving.m | 33 +++++++++++++++++++++--- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/Headers/Foundation/NSKeyValueObserving.h b/Headers/Foundation/NSKeyValueObserving.h index 8b1f4522c..a6bb14a58 100644 --- a/Headers/Foundation/NSKeyValueObserving.h +++ b/Headers/Foundation/NSKeyValueObserving.h @@ -138,10 +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; - + forKeyPath: (NSString*)aPath + context: (void *)context; +#endif @end @interface NSArray (NSKeyValueObserverRegistration) diff --git a/Source/NSKeyValueObserving.m b/Source/NSKeyValueObserving.m index 727b47fd2..fe6d1a498 100644 --- a/Source/NSKeyValueObserving.m +++ b/Source/NSKeyValueObserving.m @@ -1566,9 +1566,36 @@ cifframe_callback(ffi_cif *cif, void *retp, void **args, void *user) forKeyPath: (NSString*)aPath context: (void*)context { - [NSException raise: NSGenericException - format: @"[%@-%@]: This class is not observable", - NSStringFromClass([self class]), NSStringFromSelector(_cmd)]; + 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 From 75965866a12ab0a2de57fbb862fd885bafae4f18 Mon Sep 17 00:00:00 2001 From: Gregory Casamento Date: Fri, 15 Sep 2023 14:39:33 -0400 Subject: [PATCH 5/9] Fix compilation error --- Source/NSKeyValueObserving.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/NSKeyValueObserving.m b/Source/NSKeyValueObserving.m index fe6d1a498..4c8e8df51 100644 --- a/Source/NSKeyValueObserving.m +++ b/Source/NSKeyValueObserving.m @@ -1568,7 +1568,7 @@ cifframe_callback(ffi_cif *cif, void *retp, void **args, void *user) { GSKVOPathInfo *pathInfo; - [iLock lock]; + [kvoLock lock]; pathInfo = (GSKVOPathInfo*)NSMapGet(paths, (void*)aPath); if (pathInfo != nil) { @@ -1595,7 +1595,7 @@ cifframe_callback(ffi_cif *cif, void *retp, void **args, void *user) } } } - [iLock unlock]; + [kvoLock unlock]; } @end From 19977930f5ec7f224a09fefc058e2cfa50622307 Mon Sep 17 00:00:00 2001 From: Gregory Casamento Date: Fri, 15 Sep 2023 14:46:01 -0400 Subject: [PATCH 6/9] Add skeletal version of removeObserver:fromObjectsAtIndexes:forKeyPath:context: --- Source/NSKeyValueObserving.m | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Source/NSKeyValueObserving.m b/Source/NSKeyValueObserving.m index 4c8e8df51..f3614abf7 100644 --- a/Source/NSKeyValueObserving.m +++ b/Source/NSKeyValueObserving.m @@ -1598,6 +1598,13 @@ cifframe_callback(ffi_cif *cif, void *retp, void **args, void *user) [kvoLock unlock]; } +- (void)removeObserver:(NSObject *)observer + fromObjectsAtIndexes:(NSIndexSet *)indexes + forKeyPath:(NSString *)keyPath + context:(void *)context +{ +} + @end /** From 4b54990846ed32b5d4bcb7c9f2cc8b27e74f4d59 Mon Sep 17 00:00:00 2001 From: Gregory John Casamento Date: Fri, 15 Sep 2023 14:57:29 -0400 Subject: [PATCH 7/9] Move info method to the right place --- Source/NSKeyValueObserving.m | 87 ++++++++++++++++++------------------ 1 file changed, 44 insertions(+), 43 deletions(-) diff --git a/Source/NSKeyValueObserving.m b/Source/NSKeyValueObserving.m index f3614abf7..5055daa39 100644 --- a/Source/NSKeyValueObserving.m +++ b/Source/NSKeyValueObserving.m @@ -1288,6 +1288,50 @@ 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]; +} + +- (void)removeObserver:(NSObject *)observer + fromObjectsAtIndexes:(NSIndexSet *)indexes + forKeyPath:(NSString *)keyPath + context:(void *)context +{ +} + @end @implementation NSKeyValueObservationForwarder @@ -1562,49 +1606,6 @@ cifframe_callback(ffi_cif *cif, void *retp, void **args, void *user) } -- (void) removeObserver: (NSObject*)anObserver - forKeyPath: (NSString*)aPath - context: (void*)context -{ - GSKVOPathInfo *pathInfo; - - [kvoLock 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; - } - } - } - [kvoLock unlock]; -} - -- (void)removeObserver:(NSObject *)observer - fromObjectsAtIndexes:(NSIndexSet *)indexes - forKeyPath:(NSString *)keyPath - context:(void *)context -{ -} - @end /** From 788606f424d6a99bc2de5dfdfb00ecaab9329313 Mon Sep 17 00:00:00 2001 From: Gregory Casamento Date: Fri, 15 Sep 2023 14:59:33 -0400 Subject: [PATCH 8/9] Add method which calls info implementation --- Source/NSKeyValueObserving.m | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/Source/NSKeyValueObserving.m b/Source/NSKeyValueObserving.m index 5055daa39..406d6a705 100644 --- a/Source/NSKeyValueObserving.m +++ b/Source/NSKeyValueObserving.m @@ -1605,6 +1605,31 @@ 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 From f73efa4f89c8cc0dfb8a3b2d5ca8bd62d2980802 Mon Sep 17 00:00:00 2001 From: Gregory John Casamento Date: Fri, 15 Sep 2023 15:15:10 -0400 Subject: [PATCH 9/9] Remove reference to method we are not implementing at this point --- Source/NSKeyValueObserving.m | 7 ------- 1 file changed, 7 deletions(-) diff --git a/Source/NSKeyValueObserving.m b/Source/NSKeyValueObserving.m index 406d6a705..a375d51ec 100644 --- a/Source/NSKeyValueObserving.m +++ b/Source/NSKeyValueObserving.m @@ -1325,13 +1325,6 @@ cifframe_callback(ffi_cif *cif, void *retp, void **args, void *user) [iLock unlock]; } -- (void)removeObserver:(NSObject *)observer - fromObjectsAtIndexes:(NSIndexSet *)indexes - forKeyPath:(NSString *)keyPath - context:(void *)context -{ -} - @end @implementation NSKeyValueObservationForwarder