Селекторы в Objective-C? - PullRequest
       20

Селекторы в Objective-C?

120 голосов
/ 10 апреля 2009

Во-первых, я не уверен, что действительно понимаю, что такое селектор. Насколько я понимаю, это имя метода, и вы можете назначить его классу типа «SEL», а затем запустить методы, такие как responseToSelector, чтобы увидеть, реализует ли получатель этот метод. Может кто-нибудь предложить лучшее объяснение?

Во-вторых, к этому моменту у меня есть следующий код:

NSString *thing = @"Hello, this is Craig";

SEL sel = @selector(lowercaseString:);
NSString *lower = (([thing respondsToSelector:sel]) ? @"YES" : @"NO");
NSLog (@"Responds to lowercaseString: %@", lower);
if ([thing respondsToSelector:sel]) //(lower == @"YES")
    NSLog(@"lowercaseString is: %@", [thing lowercaseString]);

Однако, хотя thing явно является разновидностью NSString и должен отвечать на lowercaseString, я не могу получить условное выражение «responsedsToSelector» для возврата «ДА» ...

Ответы [ 8 ]

176 голосов
/ 10 апреля 2009

Вы должны быть очень осторожны с именами методов. В этом случае имя метода просто «lowercaseString», а не «lowercaseString:» (обратите внимание на отсутствие двоеточия). Вот почему вы получаете NO, потому что NSString объекты отвечают на сообщение lowercaseString, но не lowercaseString:.

Как вы знаете, когда добавить двоеточие? Вы добавляете двоеточие к имени сообщения, если добавляете двоеточие при его вызове, что происходит, если он принимает один аргумент. Если он принимает нулевые аргументы (как в случае lowercaseString), то двоеточие отсутствует. Если требуется более одного аргумента, необходимо добавить дополнительные имена аргументов вместе с их двоеточиями, как в compare:options:range:locale:.

Вы также можете посмотреть документацию и заметить наличие или отсутствие конечного двоеточия.

10 голосов
/ 10 апреля 2009

Селекторы - это эффективный способ ссылки на методы непосредственно в скомпилированном коде - компилятор - это то, что фактически присваивает значение SEL.

Другие уже охватили вторую часть вашего q, знак «:» в конце соответствует подписи, отличной от той, которую вы ищете (в этом случае эта подпись не существует).

10 голосов
/ 10 апреля 2009

Это потому, что вы хотите @selector(lowercaseString), а не @selector(lowercaseString:). Есть небольшая разница: второй подразумевает параметр (обратите внимание на двоеточие в конце), но - [NSString lowercaseString] не принимает параметр.

5 голосов
/ 10 апреля 2009

В этом случае имя селектора неверно. Двоеточие здесь является частью сигнатуры метода; это означает, что метод принимает один аргумент. Я верю, что вы хотите

SEL sel = @selector(lowercaseString);
3 голосов
/ 10 апреля 2009

Метод NSString lowercaseString (0 аргументов), а не lowercaseString: (1 аргумент).

1 голос
/ 11 апреля 2009

Не думайте о двоеточии как о части имени функции, думайте о нем как о разделителе, если у вас нет ничего для разделения (нет значения для функции), тогда вам это не нужно.

Я не уверен, почему, но все эти OO-вещи кажутся разработчикам Apple чуждыми. Я настоятельно рекомендую взять Visual Studio Express и поиграть с этим тоже. Не потому, что одно лучше другого, просто это хороший способ взглянуть на вопросы дизайна и способы мышления.

Как

introspection = reflection
+ before functions/properties = static
- = instance level

Всегда хорошо смотреть на проблему по-разному, и программирование - это загадка.

0 голосов
/ 10 августа 2018

Согласно документам Apple: https://developer.apple.com/library/archive/documentation/General/Conceptual/DevPedia-CocoaCore/Selector.html

Селектор - это имя, используемое для выбора метода для выполнения объекта, или уникальный идентификатор, который заменяет имя при компиляции исходного кода. Селектор сам по себе ничего не делает. Это просто определяет метод. Единственное, что отличает имя метода селектора от простой строки, это то, что компилятор обеспечивает уникальность селекторов. Что делает селектор полезным, так это то, что (в сочетании со временем выполнения) он действует как указатель динамической функции, который для данного имени автоматически указывает на реализацию метода, подходящего для любого класса, с которым он используется. Предположим, у вас есть селектор для запуска метода и классы Dog, Athlete и ComputerSimulation (в каждом из которых реализован метод run). Селектор может использоваться с экземпляром каждого из классов для вызова его метода run, даже если реализация может отличаться для каждого.

Пример: (lldb) точка останова - выбор селектора viewDidLoad

Это установит точку останова во всех реализациях viewDidLoad в вашем приложении. Таким образом, селектор является своего рода глобальным идентификатором метода.

0 голосов
/ 17 октября 2014

Из моего понимания документации Apple селектор представляет собой имя метода, который вы хотите вызвать. Хорошая вещь о селекторах - вы можете использовать их в тех случаях, когда точный вызываемый метод варьируется В качестве простого примера вы можете сделать что-то вроде:

SEL selec;
if (a == b) {
selec = @selector(method1)
}
else
{
selec = @selector(method2)
};
[self performSelector:selec];
...