Po pierwsze, nie jestem pewien, czy naprawdę rozumiem, czym jest selektor. W moim rozumieniu jest to nazwa metody i można ją przypisać do klasy typu „SEL”, a następnie uruchomić metody, takie jak respondToSelector, aby sprawdzić, czy odbiornik implementuje tę metodę. Czy ktoś może zaoferować lepsze wyjaśnienie?
Po drugie, do tego momentu mam następujący kod:
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]);
Jednak mimo że thing
jest to wyraźnie rodzaj NSString i powinien odpowiadać na lowercaseString, nie mogę uzyskać warunku „respondsToSelector”, aby zwrócić „YES” ...
objective-c
selector
Craig
źródło
źródło
Odpowiedzi:
Musisz bardzo uważać na nazwy metod. W tym przypadku nazwa metody to po prostu „
lowercaseString
”, a nie „lowercaseString:
” (zwróć uwagę na brak dwukropka). Dlatego jesteśNO
zwracany, ponieważNSString
obiekty odpowiadają nalowercaseString
wiadomość, ale nie nalowercaseString:
wiadomość.Skąd wiesz, kiedy dodać okrężnicę? Dodaj dwukropek do nazwy wiadomości, jeśli chcesz dodać dwukropek podczas jej wywoływania, co dzieje się, gdy przyjmuje jeden argument. Jeśli przyjmuje zero argumentów (jak w przypadku
lowercaseString
), nie ma dwukropka. Jeśli wymaga więcej niż jednego argumentu, musisz dodać dodatkowe nazwy argumentów wraz z ich dwukropkami, jak wcompare:options:range:locale:
.Możesz również przejrzeć dokumentację i zauważyć obecność lub brak końcowego dwukropka.
źródło
Selektory są skutecznym sposobem odwoływania się do metod bezpośrednio w skompilowanym kodzie - kompilator jest tym, co faktycznie przypisuje wartość do SEL.
Inne zajęły się już drugą częścią twojego q, ':' na końcu pasuje do innego podpisu niż ten, którego szukasz (w tym przypadku ten podpis nie istnieje).
źródło
To dlatego, że chcesz
@selector(lowercaseString)
, a nie@selector(lowercaseString:)
. Jest subtelna różnica: druga oznacza parametr (zwróć uwagę na dwukropek na końcu), ale- [NSString lowercaseString]
nie przyjmuje parametru.źródło
W tym przypadku nazwa selektora jest nieprawidłowa. Dwukropek jest tutaj częścią sygnatury metody; oznacza to, że metoda przyjmuje jeden argument. Wierzę, że chcesz
źródło
Metoda NSString to
lowercaseString
(0 argumentów), a nielowercaseString:
(1 argument).źródło
Nie myśl o dwukropku jako o części nazwy funkcji, myśl o nim jako o separatorze, jeśli nie masz nic do rozdzielenia (brak wartości, którą można by przypisać do funkcji), nie potrzebujesz tego.
Nie jestem pewien, dlaczego, ale wszystkie te rzeczy OO wydają się być obce programistom Apple. Zdecydowanie sugerowałbym pobranie Visual Studio Express i zabawę z tym. Nie dlatego, że jeden jest lepszy od drugiego, po prostu jest to dobry sposób na przyjrzenie się problemom projektowym i sposobom myślenia.
Lubić
Zawsze dobrze jest spojrzeć na problem w inny sposób, a programowanie jest ostateczną zagadką.
źródło
Z mojego zrozumienia dokumentacji Apple wynika, że selektor reprezentuje nazwę metody, którą chcesz wywołać. Zaletą selektorów jest to, że można ich używać w przypadkach, gdy dokładna metoda jest różna. Jako prosty przykład możesz zrobić coś takiego:
źródło
Zgodnie z dokumentami Apple: https://developer.apple.com/library/archive/documentation/General/Conceptual/DevPedia-CocoaCore/Selector.html
Przykład: (lldb) punkt przerwania --set selector viewDidLoad
Spowoduje to ustawienie punktu przerwania we wszystkich implementacjach viewDidLoad w Twojej aplikacji. Więc selector jest rodzajem globalnego identyfikatora metody.
źródło