tags:

views:

1242

answers:

5

I have a class that I'm encapsulating ABRecordID with and when it's used as a key to add to an NSMutableDictionary, I get the run-time exception:

"NSInvalidArgumentException: *** -[MyRecordId copyWithZone:]: unrecognized selector sent to instance"

MyRecordId declared as:

@interface MyRecordId : NSObject {
    ABRecordID abRecordId;
}

-(id)initWithId:(ABRecordID)anABRecordId;
@property (nonatomic) ABRecordID abRecordId;

@end

Adding to dictionary:

NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
MyRecordId *recordId = [[MyRecordId alloc] initWithId:anABRecordId];
[dict setObject:@"hello" forKey:recordId];

The last line causes the exception.. I know that you can't store non-object types as keys for a dictionary but I thought that wrapping it up in NSObject derived class would make it okay.

Am I not supposed to store ABRecordID in other objects? Should I be doing something else?

+1  A: 

NSDictionary keys need to implement the NSCopying protocol. That's why it's telling you your object doesn't respond to copyWithZone:.

Chuck
+1  A: 

The class of the object you use as a key value should conform to the NSCopying protocol. Basically it should implement the copyWithZone: method.

Instead of using your own class to wrap your non-object variable in, you should use NSValue class, which is designed for this purpose and supports the NSCopying protocol.

Diederik Hoogenboom
I didn't know that NSValue was best suited for this purpose. Which initializer would I use to constructing it with 'ABRecordID'?
Robin Jamieson
A: 

You can also use NSNumber for this purpose as it inherits from NSValue.

Alexi Groove
A: 

Diederik is on the right path, but given the type of ABRecordID, I'd recommend using NSNumber (an NSValue subclass). You'd use -initWithInt: for ABRecordID which is an int32_t.

Rob Napier
+4  A: 

Use NSNumber to store the ABRecordID in an Obj-C class:

[dict setObject:@"hello" forKey:[NSNumber numberWithInt:recordId]];

to obtain the recordId again, do:

recordId = [[dict objectForKey:@"hello"] intValue];
Marco Mustapic