2009-06-25 13 views
6

tengo una clase que estoy encapsular ABRecordID con y cuando se utiliza como una clave para agregar a una NSMutableDictionary, consigo la excepción de tiempo de ejecución:NSInvalidArgumentException excepción/copyWithZone con NSMutableDictionary

"NSInvalidArgumentException: *** - [MyRecordId copyWithZone:]: selector no reconocido enviado a instancia"

MyRecordId declararse como:

@interface MyRecordId : NSObject { 
    ABRecordID abRecordId; 
} 

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

@end 

Adición de diccionario:

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

La última línea hace que la excepción .. Sé que no se puede almacenar tipos de objetos no como claves en un diccionario, pero pensé que envolviéndolo en la clase derivada NSObject lo haría bien.

¿No se supone que debo almacenar ABRecordID en otros objetos? ¿Debo hacer algo más?

Respuesta

7

Uso NSNumber para almacenar el ABRecordID en una clase Obj-C:

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

para obtener el recordId de nuevo, hacer:

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

NSLas claves dinámicas deben implementar el protocolo NSCopying. Es por eso que le dice que su objeto no responde al copyWithZone:.

6

La clase del objeto que utiliza como valor clave debe ajustarse al protocolo NSCopying. Básicamente debe implementar el método copyWithZone:.

En lugar de utilizar su propia clase para envolver su variable no objeto, debe usar la clase NSValue, que está diseñada para este propósito y es compatible con el protocolo NSCopying.

+0

No sabía que NSValue era el más adecuado para este propósito. ¿Qué inicializador usaría para construirlo con 'ABRecordID'? –

+2

Voy con 'NSValue valueWithNonretainedObject' personalmente, debería funcionar para usted. Solo ten en cuenta que no mantendrá tu objeto para ti, por supuesto ... – Chris

0

También puede usar NSNumber para este fin, ya que hereda de NSValue.

0

Diederik está en el camino correcto, pero dado el tipo de ABRecordID, recomendaría usar NSNumber (una subclase NSValue). Utilizaría -initWithInt: para ABRecordID que es int32_t.

1

Para la codificación desafiado como yo, asegúrese de que los argumentos para setObject son el camino correcto. ¡Perdí horas en este error antes de darme cuenta de que las había invertido!

+0

dulce cristo, este fue precisamente mi problema también, gracias – ardnew

Cuestiones relacionadas