NSInvalidArgumentException / copyWithZone исключение с NSMutableDictionary - PullRequest
6 голосов
/ 25 июня 2009

У меня есть класс, с которым я инкапсулирую ABRecordID, и когда он используется в качестве ключа для добавления в NSMutableDictionary, я получаю исключение времени выполнения:

"NSInvalidArgumentException: *** - [MyRecordId copyWithZone:]: нераспознанный селектор отправлен Экземпляр "

MyRecordId объявлен как:

@interface MyRecordId : NSObject {
    ABRecordID abRecordId;
}

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

@end

Добавление в словарь:

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

Последняя строка вызывает исключение. Я знаю, что вы не можете хранить не-объектные типы в качестве ключей для словаря, но я подумал, что завершение его в производном классе NSObject сделает все в порядке.

Разве я не должен хранить ABRecordID в других объектах? Должен ли я делать что-то еще?

Ответы [ 6 ]

7 голосов
/ 25 июня 2009

Используйте NSNumber для хранения ABRecordID в классе Obj-C:

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

чтобы снова получить recordId, выполните:

recordId = [[dict objectForKey:@"hello"] intValue];
6 голосов
/ 25 июня 2009

Класс объекта, который вы используете в качестве значения ключа, должен соответствовать протоколу NSCopying. По сути, он должен реализовывать метод copyWithZone:.

Вместо того, чтобы использовать собственный класс для переноса необъектной переменной, вы должны использовать класс NSValue, который предназначен для этой цели и поддерживает протокол NSCopying.

6 голосов
/ 25 июня 2009

Ключи NSDictionary должны реализовывать протокол NSCopying. Вот почему он говорит вам, что ваш объект не отвечает на copyWithZone:.

1 голос
/ 19 февраля 2012

Для такой сложной задачи, как я, убедитесь, что аргументы setObject правильные. Я просто потратил часы на эту ошибку, прежде чем заметил, что я их перевернул!

0 голосов
/ 25 июня 2009

Diederik находится на правильном пути, но учитывая тип ABRecordID, я бы рекомендовал использовать NSNumber (подкласс NSValue). Вы бы использовали -initWithInt: для ABRecordID, то есть int32_t.

0 голосов
/ 25 июня 2009

Вы также можете использовать NSNumber для этой цели, поскольку он наследуется от NSValue.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...