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


122

По-перше, я не впевнений, що насправді розумію, що таке селектор. Наскільки я розумію, це ім'я методу, і ви можете призначити його класу типу 'SEL', а потім запустити такі методи, як RespoToSelector, щоб побачити, чи приймає цей метод приймач. Чи може хтось запропонувати краще пояснення?

По-друге, до цього моменту у мене є такий код:

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, і він повинен відповідати нижньому регістру, я не можу умовити повернення "ТАК" "respondsToSelector" ...


Ви хочете прочитати опис Selector на веб-сайті розробника Apple: Selectors .
lothar

14
Стенфордський курс CS193P завдання 1В? У мене тут точно таке ж питання! :)
Корстіан Бурман

Відповіді:


181

Ви повинні бути дуже обережними щодо назв методів. У цьому випадку назва методу є просто " lowercaseString", а не " lowercaseString:" (відзначте відсутність товстої кишки). Ось чому ви NOповертаєтесь, оскільки NSStringоб’єкти відповідають на lowercaseStringповідомлення, а не на lowercaseString:повідомлення.

Як ви знаєте, коли додати двокрапку? Ви додасте двокрапку до імені повідомлення, якщо ви додасте двокрапку під час його виклику, що трапляється, якщо він бере один аргумент. Якщо він бере нульові аргументи (як у випадку lowercaseString), то двокрапки немає. Якщо потрібно більше ніж один аргумент, вам доведеться додати додаткові назви аргументів разом з їх двокрапками, як у compare:options:range:locale:.

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


12

Селектори - це ефективний спосіб посилатися на методи безпосередньо у компільований код - компілятор - це те, що фактично присвоює значення SEL.

Інші вже охопили другу частину вашого q, ':' в кінці відповідає іншому підпису, ніж те, що ви шукаєте (у цьому випадку підпису не існує).


10

Це тому, що ти хочеш @selector(lowercaseString), ні @selector(lowercaseString:). Існує тонка різниця: другий має на увазі параметр (відмітьте двокрапку в кінці), але - [NSString lowercaseString]не приймає параметр.


5

У цьому випадку ім'я селектора неправильне. Двокрапка тут є частиною підпису методу; це означає, що метод бере один аргумент. Я вірю, що ти хочеш

SEL sel = @selector(lowercaseString);


1

Не думайте про товсту кишку як частину назви функції, думайте про це як про роздільник, якщо у вас немає нічого для розділення (значення не має для функції), тоді воно вам не потрібно.

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

Подібно до

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

Завжди добре дивитися на проблему по-різному, а програмування - це найкраща загадка.


0

З мого розуміння документації Apple, селектор представляє назву методу, який потрібно зателефонувати. Приємна річ, що стосується селекторів - це те, що ви можете використовувати їх у випадках, коли точний метод, який потрібно викликати, відрізняється. Як простий приклад, ви можете зробити щось на кшталт:

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

0

Відповідно до документів Apple: https://developer.apple.com/library/archive/documentation/General/Conceptual/DevPedia-CocoaCore/Selector.html

Селектор - це ім'я, яке використовується для вибору методу для виконання об'єкта, або унікальний ідентифікатор, який замінює ім'я при складанні вихідного коду. Селектор сам по собі нічого не робить. Він просто ідентифікує метод. Єдине, що відрізняє назву методу селектора від звичайної рядки, це те, що компілятор гарантує, що селектори унікальні. Що робить селектор корисним, це те, що він (у поєднанні з програмою виконання) діє як покажчик динамічної функції, який для даного імені автоматично вказує на реалізацію методу, відповідного тому класу, який він використовується. Припустимо, у вас був селектор для запуску методу та класи Dog, Athlete та ComputerSimulation (кожен з яких реалізував запуск методу).

Приклад: (lldb) точка перелому - набір селекторів переглядуDidLoad

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.