NSMutableDictionary с UIButton * как ключи - разработка iPhone
Я новичок в разработке iPhone, и у меня есть вопрос, который может иметь очень простой ответ. Я пытаюсь добавить кнопки в представление, и эти кнопки связаны с настраиваемым классом, который я определил. Когда я добавляю кнопки в представление, я хотел бы знать, какой класс соответствует этим кнопкам. Это связано с тем, что, когда я нажимаю кнопку, мне нужно получить некоторую информацию о классе, но получателем сообщения является другой класс. Я не мог найти информацию об ошибке, которую я получаю в Интернете. Проблема в том, что я пытаюсь создать NSMutableDictionary, где ключи имеют тип UIButton *, и значения имеют мой собственный тип:
// create button for unit
UIButton* unitButton = [[UIButton alloc] init];
[sourceButtonMap setObject:composite forKey:unitButton];
Конечно, sourceButtonMap определен в классе и инициализируется в функции init как sourceButtonMap = [[NSMutableDictionary alloc] init];
Ошибка, возникающая при попытке добавить пару ключ-значение:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[UIButton copyWithZone:]: unrecognized selector sent to instance 0x3931e90'
Это происходит, потому что я не могу хранить UIButton * в качестве ключей?
Может ли кто-нибудь указать мне, почему я получаю эту ошибку? Спасибо всем,
аа
Ответы
Ответ 1
Один из способов, который я нашел, - использовать конструкцию NSValue для использования в качестве ключа. Чтобы создать это использование:
[NSValue valueWithNonretainedObject:myButton]
.
Здесь оговорка, похоже, состоит в том, что, если кнопка содержит мусор, ключ будет содержать недопустимую ссылку.
Вы снова можете получить ссылку на UIButton, пропуская через словарь следующим образом:
for (NSValue* nsv in myDict) {
UIButton* b = (UIButton*)[nsv nonretainedObjectValue];
...
}
Ответ 2
Из Документы Apple:
Ключ скопирован (используя copyWithZone:; ключи должны соответствовать протокол NSCopying).
UIButton не соответствует протоколу NSCopying, поэтому вы не можете использовать его в качестве ключа в NSDictionary
Ответ 3
У меня классный трюк.
Я передал указатель на int (так как это действительно все указатель) и сохраните его в NSNumber. Использование NSNumber в качестве ключа решает эту проблему и имеет смысл фундаментально, потому что кто-то заботится о сохранении копии кнопки в словаре? Мне более удобно хранить копию информации указателя.
Если вы, как я, вы, вероятно, включите этот бит в макрос. Что-то вроде этого:
#define BOX_AS_NUM(_ptr_) [NSNumber numberWithInt:(int)_ptr_]
Затем он немного чище использовать в коде...
NSDictionary* btnMap = [NSDictionary dictionaryWithObjectsAndKeys:some_obj, BOX_AS_NUM(some_btn), nil];
-(IBAction)someBtnAction:(id)sender
{
SomeObj* obj = [btnMap objectForKey:BOX_AS_NUM(sender)];
[obj doCoolStuffBecuaseIWasJustClicked];
}
Ответ 4
UIButtons имеет свойство description
, которое может использоваться как ключ словаря:
NSMutableDictionary *myDictionary = [[NSMutableDictionary alloc] initWithCapacity:1];
UIButton *myButton = [[UIButton alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 10.0f, 10.0f)];
id myObject;
[myDictionary setObject:myObject forKey:myButton.description];
// somewhere else in code
id myLookedUpObject = [myDictionary objectForKey:myButton.description];
// do something with myLookedUpObject