Überprüfen Sie, ob eine Methode vorhanden ist

110

Kann ich auf irgendeine Weise testen, ob in Objective-C eine Methode vorhanden ist?

Ich versuche, einen Schutz hinzuzufügen, um festzustellen, ob mein Objekt über die Methode verfügt, bevor ich es aufrufe.

teepusink
quelle
Es stellt sich auch die Frage, ob dies überhaupt der richtige Ansatz ist, da Objective-C-Klassen auf Selektoren antworten können, die sie nicht deklariert haben (via - forwardInvocation:).
Donal Fellows

Antworten:

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

Es gibt auch den statischen NachrichteninstanzenRespondToSelector : (SEL) -Selektor Sie würden ihn so nennen:

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

oder so:

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

Dies kann nützlich sein, wenn Sie abhängig davon einen oder einen anderen Konstruktor aufrufen möchten (ich meine, bevor Sie die Instanz selbst haben).

Ricard Pérez del Campo
quelle
1
Was unterscheidet InstanzenRespondToSelector von RespondsToSelector?
CReaTuS
1
Der Hauptunterschied besteht darin, dass eine eine Instanznachricht ist (um zu testen, ob eine bestimmte Instanznachricht vorhanden ist), während die andere eine Klassennachricht ist (um zu testen, ob eine bestimmte Klassennachricht vorhanden ist).
Ricard Pérez del Campo
1
+1 Für [MyClass instanceRespondToSelector]. Ich brauchte es innerhalb einer Init-Erstellungsmethode: Wenn eine Unterklasse erforderlich ist, muss möglicherweise eine Super-Init-Methode anstelle anderer (veralteter) aufgerufen werden, da self noch nicht erstellt wurde und responsToSelector immer NO zurückgibt.
LightMan
12

Verwenden Sie respondsToSelector:. Aus der Dokumentation :

replyToSelector:

Gibt einen booleschen Wert zurück, der angibt, ob der Empfänger eine Methode implementiert oder erbt, die auf eine bestimmte Nachricht antworten kann.

- (BOOL)respondsToSelector:(SEL)aSelector

Parameter
aSelector - Ein Selektor, der eine Nachricht identifiziert.

Rückgabewert,
YES wenn der Empfänger eine Methode implementiert oder erbt , die andernfalls auf aSelector reagieren kann NO.

Carl Norum
quelle
10

Sie suchen nach AntwortenToSelector: -

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

Wie Donal sagt, sagt Ihnen das Obige, dass foo definitiv mit dem Empfang des Balkenwählers umgehen kann . Wenn foo jedoch ein Proxy ist, der Balken an ein zugrunde liegendes Objekt weiterleitet, das die Balkennachricht empfängt, antwortetToSelector: NEIN, obwohl die Nachricht an ein Objekt weitergeleitet wird, das auf Balken antwortet.

Frank Shearar
quelle
1

Das Überprüfen von Selektoren mit responsondsToSelector gilt normalerweise nur für Delegatmethoden. Sie sollten nicht forwardInvocation oder Proxys für Delegatmethoden verwenden. Wenn Sie respondsToSelector in anderen Situationen verwenden müssen, möchten Sie möglicherweise sicherstellen, dass es keine geeignetere Methode zum Entwerfen Ihres Programms gibt.

Eric
quelle