diff --git a/Source/NSConcreteHashTable.m b/Source/NSConcreteHashTable.m index 6dc953246..3a4451aca 100644 --- a/Source/NSConcreteHashTable.m +++ b/Source/NSConcreteHashTable.m @@ -457,11 +457,20 @@ @interface NSConcreteHashTable : NSHashTable GSIMapAddKey(t, (GSIMapKey)element); ((NSConcreteHashTable*)table)->version++; } - else if (element != n->key.ptr) - { - GSI_MAP_RELEASE_KEY(t, n->key); - n->key = (GSIMapKey)element; - GSI_MAP_RETAIN_KEY(t, n->key); + else if (GSI_MAP_READ_KEY(t, &n->key).ptr != element) + { + if (t->legacy) + { + t->cb.old.release(t, n->key.ptr); + n->key = (GSIMapKey)element; + t->cb.old.retain(t, n->key.ptr); + } + else + { + pointerFunctionsRelinquish(&t->cb.pf, (void**)&n->key); + pointerFunctionsReplace(&t->cb.pf, (void**)&n->key, + (void*)element); + } ((NSConcreteHashTable*)table)->version++; } } @@ -854,11 +863,19 @@ - (void) addObject: (id)anObject GSIMapAddKey(t, (GSIMapKey)anObject); version++; } - else if (n->key.obj != anObject) + else if (GSI_MAP_READ_KEY(t, &n->key).ptr != anObject) { - GSI_MAP_RELEASE_KEY(t, n->key); - n->key = (GSIMapKey)anObject; - GSI_MAP_RETAIN_KEY(t, n->key); + if (t->legacy) + { + t->cb.old.release(t, n->key.ptr); + n->key.ptr = anObject; + t->cb.old.retain(t, n->key.ptr); + } + else + { + pointerFunctionsRelinquish(&t->cb.pf, (void**)&n->key); + pointerFunctionsReplace(&t->cb.pf, (void**)&n->key, (void*)anObject); + } version++; } } diff --git a/Source/NSConcreteMapTable.m b/Source/NSConcreteMapTable.m index fb71dd752..f2441bbd9 100644 --- a/Source/NSConcreteMapTable.m +++ b/Source/NSConcreteMapTable.m @@ -641,7 +641,18 @@ @interface NSConcreteMapTable : NSMapTable } else if (GSI_MAP_READ_VALUE(t, &n->value).ptr != value) { - GSI_MAP_STORE_VALUE(t, &n->value, (GSIMapVal)value); + if (t->legacy) + { + t->cb.old.v.release(t, n->value.ptr); + n->value = (GSIMapVal)value; + t->cb.old.v.retain(t, n->value.ptr); + } + else + { + pointerFunctionsRelinquish(&t->cb.pf.v, (void**)&n->value); + pointerFunctionsReplace(&t->cb.pf.v, (void**)&n->value, + (void*)value); + } t->version++; } } @@ -1380,7 +1391,18 @@ - (void) setObject: (id)anObject forKey: (id)aKey { if (GSI_MAP_READ_VALUE(self, &node->value).obj != anObject) { - GSI_MAP_STORE_VALUE(self, &node->value, (GSIMapVal)anObject); + if (self->legacy) + { + self->cb.old.v.release(self, node->value.ptr); + node->value = (GSIMapVal)anObject; + self->cb.old.v.retain(self, node->value.ptr); + } + else + { + pointerFunctionsRelinquish(&self->cb.pf.v, (void**)&node->value); + pointerFunctionsReplace(&self->cb.pf.v, (void**)&node->value, + (void*)anObject); + } version++; } } diff --git a/Tests/base/NSHashTable/general.m b/Tests/base/NSHashTable/general.m index 1de6b0524..2e6b6caa4 100644 --- a/Tests/base/NSHashTable/general.m +++ b/Tests/base/NSHashTable/general.m @@ -6,6 +6,14 @@ @interface MyClass: NSObject @end @implementation MyClass +- (NSUInteger) hash +{ + return 42; +} +- (BOOL) isEqual: (id)other +{ + return [other isKindOfClass: [self class]]; +} #if 0 - (oneway void) release { @@ -27,6 +35,7 @@ int main() NSAutoreleasePool *arp = [NSAutoreleasePool new]; NSHashTable *t; MyClass *o; + MyClass *o2; int c; t = [[NSHashTable alloc] initWithOptions: NSHashTableObjectPointerPersonality @@ -63,8 +72,17 @@ int main() [t removeObject: o]; PASS([o retainCount] == c, "remove from hash table decrements retain count") + o2 = [MyClass new]; + PASS([o2 retainCount] == 1, "initial retain count of second object OK") + + [t addObject: o]; + [t addObject: o2]; + PASS([o retainCount] == 1, "first object was removed") + PASS([o2 retainCount] == 2, "second object was added") + RELEASE(t); RELEASE(o); + RELEASE(o2); [arp release]; arp = nil; return 0; diff --git a/Tests/base/NSMapTable/general.m b/Tests/base/NSMapTable/general.m index 0c035323c..379686443 100644 --- a/Tests/base/NSMapTable/general.m +++ b/Tests/base/NSMapTable/general.m @@ -6,6 +6,14 @@ @interface MyClass: NSObject @end @implementation MyClass +- (NSUInteger) hash +{ + return 42; +} +- (BOOL) isEqual: (id)other +{ + return [other isKindOfClass: [self class]]; +} #if 0 - (oneway void) release { @@ -27,6 +35,7 @@ int main() NSAutoreleasePool *arp = [NSAutoreleasePool new]; NSMapTable *t; MyClass *o; + MyClass *o2; int c; t = [[NSMapTable alloc] initWithKeyOptions: NSMapTableObjectPointerPersonality @@ -78,8 +87,15 @@ int main() [t removeObjectForKey: @"a"]; PASS([o retainCount] == c, "remove map table val decrements retain count") + [t setObject: o forKey: @"a"]; + o2 = [MyClass new]; + [t setObject: o2 forKey: @"a"]; + PASS([o retainCount] == 1, "old instance removed") + PASS([o2 retainCount] == 2, "new instance added") + RELEASE(t); RELEASE(o); + RELEASE(o2); [arp release]; arp = nil; return 0;