Добавить метод выбора в словарь - PullRequest
17 голосов
/ 01 февраля 2010

Я хочу добавить селектор в словарь (основная цель - определить метод обратного вызова и делегат после выполнения чего-либо)

Но я обнаружил, что не могу этого сделать, программа получит ошибку «EXC_BAD_ACCESS». Есть ли другой способ добавить этот селектор методов в словарь? Спасибо за вашу помощь.

Ответы [ 4 ]

36 голосов
/ 28 декабря 2010

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

Комбинация NSStringFromSelector и NSSelectorFromString, как ответили выше, вероятно, лучший путь. Но если вы действительно хотите, вы можете использовать селектор в качестве значения или ввести NSDictionary.

Селектор (тип SEL) реализован как указатель на структуру во время выполнения Apple Objective-C. Указатель нельзя использовать непосредственно в словаре, но указатель можно заключить в объект NSValue, который можно использовать.

Используя этот метод, вы можете сохранить селектор как значение в словаре, используя такой код:

dictionary = 
  [NSDictionary dictionaryWithObject:[NSValue valueWithPointer:selector]
                              forKey:key];

Селектор может быть получен с помощью кода, подобного следующему:

SEL selector = [[dictionary objectForKey:key] pointerValue];

Аналогично использованию селектора в качестве ключа:

dictionary = 
  [NSDictionary dictionaryWithObject:value
                              forKey:[NSValue valueWithPointer:selector]];

value = [dictionary objectForKey:[NSValue valueWithPointer:selector]];
22 голосов
/ 01 февраля 2010

Добавление новой записи в словарь делает две вещи (очевидно, в дополнение к добавлению ее в словарь):

  1. Требуется копия значения ключа. Это означает, что ключевой объект должен реализовывать протокол NSCopying
  2. retain s значение. Это означает, что ему необходимо реализовать протокол NSObject

Вероятно, это вторая причина, по которой вы EXC_BAD_ACCESS.

Есть как минимум два пути решения этой проблемы.

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

Во-вторых, вы можете преобразовать селектор в строку (и обратно), используя NSSelectorFromString и NSStringFromSelector ( документы здесь ).

2 голосов
/ 01 февраля 2010

Я получаю ответ на основании комментария Zydeco:

Вы можете конвертировать между SEL и NSString с использованием NSSelectorFromString и NSStringFromSelector

1 голос
/ 01 февраля 2010

Распространенная идиома в Obj-C - иметь конкретные имена для обратных вызовов для определенных событий.(Таких parserDidBeginDocument: от NSXMLParserDelegate).Если вы действительно должны иметь возможность указывать имена, вполне вероятно, что вы можете добавить имена селекторов как @"mySelector:withArgument:context:" или как-то еще.

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