Подтвердить что ты не робот

Сохранить селектор как значение в NSDictionary

Есть ли способ сохранить селектор в NSDictionary, не сохраняя его как NSString?

4b9b3361

Ответ 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.