Есть ли способ сохранить селектор в NSDictionary
, не сохраняя его как NSString
?
Сохранить селектор как значение в NSDictionary
Ответ 1
SEL
- это просто указатель, который вы можете сохранить в NSValue
:
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
[NSValue valueWithPointer:@selector(foo)], @"foo",
nil];
Чтобы вернуть селектор, вы можете использовать:
SEL aSel = [[dict objectForKey:@"foo"] pointerValue];
Ответ 2
Альтернативой решению Georg было бы преобразование селектора в NSString перед сохранением его NSDictionary:
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
NSStringFromSelector(@selector(foo)), @"foo",
nil];
SEL selector = NSSelectorFromString([dict objectForKey:@"foo"]);
Этот метод, хотя и использует больше памяти, дает вам возможность сериализовать весь NSDictionary как строку через библиотеки, такие как JSONKit.
Ответ 3
An NSDictionary
- это действительно просто CFDictionary
, который сохраняет и освобождает все ключи и значения. Если вы создаете CFDictionary
напрямую, вы можете установить его, чтобы не сохранять и не отпускать значения. Вы можете приписать CFDictionaryRef
в NSDictionary *
и наоборот.
Ответ 4
В случае использования UILocalNotification
единственный способ - использовать NSSelectorFromString([dict objectForKey:@"foo"])
. С valueWithPointer
приложение сбой при настройке свойства userInfo объекта UILocalNotification
. Будьте осторожны.
Ответ 5
В то время как ответ Георг должен работать, NSValue
также поддерживает кодирование любого значения с использованием строки кодировки типа Objective-C, которая имеет специальный способ представления SEL
- с a ":"
(в отличие от "^v"
, созданного -valueWithPointer:
, что означает void *
).
source: Objective-C Руководство по программированию времени выполнения - Тип кодировки
Отключение решения Georg, лучший API-совместимый способ поместить SEL
в NSValue
в NSDictionary
:
// store
NSDictionary *dict = @{
@"foo": [NSValue value:&@selector(foo) withObjCType:@encode(SEL)]
};
// retrieve
SEL aSel;
[dict[@"foo"] getValue:&aSel];
Обоснование обработки SEL
как своего собственного зверя состоит в том, что документы описывают его как "непрозрачный тип" - это означает, что его внутренние действия (даже то, что он typedef
d) не соответствуют приложению программисты; Apple может смешать его в любое время в будущем.
Кроме того, использование void *
, чтобы заставить систему делать то, что вы хотите, было полезно в C обратно в 90-х, когда большинство из нас не знали ничего лучшего. Теперь ты лучше этого.
Вышеупомянутый подход должен использоваться только в том случае, если поиск SEL
происходит во время работы программы - вы не должны хранить этот NSDictionary
на диске. Если вам нужно сохранить SEL
долгосрочный (для запуска приложений), вы должны следовать подход David H и преобразовать его в NSString
.