NSDictionary objectForKey and non-standard key classes
NSDictionary objectForKey and non-standard key classes
- Subject: NSDictionary objectForKey and non-standard key classes
- From: Bob Peterson <email@hidden>
- Date: Tue, 28 Aug 2001 09:00:13 -0400
I can't get NSDictionary to work using keys from a custom class. With
NSString and NSNumber keys it works just fine. The doc for NSDictionary
says only that the key has to support isEqual: and NSCopying.
I've created a class whose objects I want to use as keys in an
NSDictionary. It inherits from NSObject and implements NSCopying and
isEqual:. But isEqual: is never called, so I wonder how it can possibly
work. In fact, it doesn't.
I can put in objects using these keys. I can even enumerate the keys and
use the keys returned by keyEnumerator to fetch objects with
objectForKey:. But if I use the original key object used to insert the
value object, I get back nil.
It is as if the key-equality function used by NSDictionary is "==",
where keys are a match only if they are the same address. Or perhaps
this is some fallout of the opaque hash functions alluded to in the docs
but that I'm not supposed to worry about. What is my key class missing?
// Skeleton.h
// KeyTest
#import <Foundation/Foundation.h>
@interface Skeleton : NSObject <NSCopying> {
NSString* value;
}
- (void) setStringValue:(NSString*)newValue;
- (NSString*) stringValue;
- (NSString*) description;
@end
// Skeleton.m
// KeyTest
#import "Skeleton.h"
@implementation Skeleton
- (id) init {
self = [super init];
if (self != nil) {
[self setStringValue:@"(NOT SET)"];
}
return self;
}
-(void) dealloc {
[value release];
value = nil;
}
- (void) setStringValue:(NSString*)newValue {
[value release];
value = [newValue retain];
}
- (NSString*) stringValue {
return value;
}
- (BOOL) isEqual:(id)otherValue {
return [value isEqual:otherValue];
}
- (id) copyWithZone:(NSZone*)zone
{
id doppleganger;
doppleganger = [[Skeleton alloc] init];
[doppleganger setStringValue:[self stringValue]];
return doppleganger;
}
- (NSString*) description {
return [NSString stringWithFormat:@"<%@>", [self stringValue]];
}
@end