Sprawdź, czy metoda istnieje


111

Czy istnieje sposób na sprawdzenie, czy metoda istnieje w Objective-C?

Próbuję dodać strażnika, aby sprawdzić, czy mój obiekt ma metodę przed jej wywołaniem.


Pojawia się również pytanie, czy jest to właściwe podejście w pierwszej kolejności, skoro klasy Objective-C mogą odpowiadać na selektory, których nie zadeklarowały (przez - forwardInvocation:).
Donal Fellows

Odpowiedzi:


189
if ([obj respondsToSelector:@selector(methodName:withEtc:)]) {
   [obj methodName:123 withEtc:456];
}

72

Istnieją również statyczne instancje wiadomościRespondToSelector : (SEL) selector Można to nazwać tak:

[MyClass instancesRespondToSelector:@selector(someMethod:withParams:)]

lub tak:

[[myObject class] instancesRespondToSelector:@selector(someMethod:withParams:)]

Może to być przydatne, jeśli chciałbyś wywołać jednego konstruktora lub innego w zależności od tego (mam na myśli, zanim będziesz mieć samą instancję).


1
Czym różni się instancesRespondToSelector od respondsToSelector?
CReaTuS,

1
Główną różnicą jest to, że jeden jest komunikatem instancji (aby sprawdzić, czy komunikat określonej instancji istnieje), a drugi jest komunikatem klasy (aby sprawdzić, czy komunikat określonej klasy istnieje).
Ricard Pérez del Campo

1
+1 dla [instancji MyClassRespondToSelector]. Potrzebowałem tego w metodzie tworzenia init: kiedy podklasy mogą być konieczne, aby wywołać jedną metodę super init zamiast innych (przestarzałe), ponieważ self nie zostało jeszcze utworzone i respondsToSelector zawsze zwróci NIE.
LightMan,

12

Użyj respondsToSelector:. Z dokumentacji :

respondsToSelector:

Zwraca wartość logiczną wskazującą, czy odbiorca implementuje, czy dziedziczy metodę, która może odpowiedzieć na określony komunikat.

- (BOOL)respondsToSelector:(SEL)aSelector

Parametry
aSelector - selektor identyfikujący wiadomość.

Wartość zwracana ,
YESjeśli odbiorca implementuje lub dziedziczy metodę, która w przeciwnym razie może odpowiedzieć na element aSelectorNO .


10

Szukasz odpowiedziToSelector: -

if ([foo respondsToSelector: @selector(bar)] {
  [foo bar];
}

Jak mówi Donal, powyższe mówi ci, że foo zdecydowanie poradzi sobie z otrzymaniem selektora paska. Jednakże, jeśli foo jest proxy, które przekazuje bar do jakiegoś bazowego obiektu, który otrzyma komunikat bar, to respondsToSelector: powie Ci NIE, nawet jeśli wiadomość zostanie przekazana do obiektu, który odpowiada na bar.


1

Sprawdzanie selektorów za pomocą respondsToSelector jest zwykle tylko dla metod delegata. Nie należy używać forwardInvocation ani serwerów proxy dla metod delegatów. Jeśli potrzebujesz użyć respondsToSelector w innych sytuacjach, możesz upewnić się, że nie ma bardziej odpowiedniego sposobu projektowania programu.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.