NSMutableDictionary setObject: сбой forKey, когда ключ является членом объекта

#objective-c #ios5 #nsmutabledictionary #sigabrt

#objective-c #ios5 #nsmutabledictionary #sigabrt

Вопрос:

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

Мое определение класса выглядит следующим образом:

 @interface ClassA : NSObject {
@public
    UIButton *button1;
    UIButton *button2;
    UILabel *label;
}

@property (nonatomic, retain) UIButton *button1;
@property (nonatomic, retain) UIButton *button2;
@property (nonatomic, retain) UILabel *label;
@end
  

И моя реализация заключается именно в этом:

 @implementation ClassA
@synthesize button1, button2, label;
@end
  

NSMutableDictionary находится в другом классе. Я определяю это в реализации следующим образом:

 @interface UIClass1 : UIViewController {
    NSMutableDictionary *Dictionary;
}

-(void)DoWork;

@property (nonatomic, retain) NSMutableDictionary *Dictionary;
@end
  

И часть, где я пытаюсь установить значения словаря, выполнена здесь:

 -(void)DoWork{
    Dictionary = [[NSMutableDictionary alloc] init];
    ObjectA = [[ClassA alloc] init];

    ObjectA->button1 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    ObjectA->button2 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    ObjectA->label = [[[UILabel alloc] initWithFrame:CGRectMake(20, 20, 20, 20)] autorelease]

    /* THIS IS A TEST AND IT WORKS FINE */
    NSString *str = [[NSString alloc] initWithFormat:@"test"];
    [Dictionary setObject:obj1 forKey:str];

    /*THIS IS WHAT I WOULD ACTUALLY LIKE TO DO */
    [Dictionary setObject:Object1 forKey:ObjectA->button1];
    [Dictionary setObject:ObjectA forKey:ObjectA->button2];
}
  

Я проследил за этим кодом через свой отладчик, и когда я добираюсь до этой строки:

 [Dictionary setObject:Object1 forKey:ObjectA->button1];
  

Это просто приводит к сбою SIGABRT. Ни одна из моих переменных не равна нулю, каждый объект был выделен.

Есть идеи относительно того, почему я не могу установить ключ для кнопки из ClassA, но я могу установить его в NSString, который я создал в качестве теста?

Комментарии:

1. эй, чувак, просто небольшое предложение: сделайте ваши переменные camelCase!

2. Хотя в этом нет необходимости, почти весь остальной исходный код Objective-C использует соглашение о нижнем регистре как для переменных, так и для методов, и верхний регистр для имен классов. Вы можете пойти против соглашения, но обычно это не рекомендуется.

3. Я действительно следую этому соглашению, приведенный выше код не является моим реальным кодом, просто макет того, что я делаю.

Ответ №1:

Объект, который вы используете в качестве ключа в NSMutableDictionary, должен соответствовать протоколу NSCopying.

Из документов Apple:

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

UIButton не соответствует NSCopying.

Комментарии:

1. А, ладно, это все объясняет. Спасибо. Есть ли где-нибудь список, в котором указано, какие объекты безопасно использовать в качестве ключа с помощью NSMutableDictionary.

2. Я не знаю списка объектов iOS Framework, которые поддерживают NSCopying, но в документах для каждого объекта указано, какие протоколы они поддерживают.

3. Вы можете использовать объект NSValue. Попробуйте [NSValue valueWithUnretainedObject:ObjectA.button1]

4. Я предполагаю, что вы имели в виду «valueWithNonretainedObject», который действительно сработал. Спасибо за отличную помощь.

5. Да, я имел в виду «valueWithNonretainedObject:»

Ответ №2:

Попробуйте использовать

 forKey:[NSValue valueWithPointer:ObjectA->button1]