it-swarm.com.de

Wie Sie die Warnung "Undeclared Selector" loswerden

Ich möchte einen Selektor für eine NSObject-Instanz verwenden ohne die Notwendigkeit eines implementierten Protokolls. Beispielsweise gibt es eine Kategoriemethode, die eine Fehlereigenschaft festlegen sollte, wenn die aufgerufene NSObject-Instanz dies unterstützt. Dies ist der Code, und der Code funktioniert wie beabsichtigt:

if ([self respondsToSelector:@selector(setError:)])
{
    [self performSelector:@selector(setError:) withObject:[NSError errorWithDomain:@"SomeDomain" code:1 userInfo:nil]];
}

Der Compiler sieht jedoch keine Methode mit der setError: -Signatur. Daher erhalte ich für jede Zeile, die das @selector(setError:) -Snippet enthält, eine Warnung:

Undeclared selector 'setError:'

Ich möchte kein Protokoll deklarieren müssen, um diese Warnung zu beseitigen, da nicht alle Klassen, die dies verwenden, etwas Besonderes implementieren sollen. Ich möchte lediglich, dass sie eine setError: - Methode oder -Eigenschaft haben.

Ist das machbar? Wie?

Prost,
EP

160
epologee

Eine andere Möglichkeit wäre, die Warnung zu deaktivieren mit:

#pragma GCC diagnostic ignored "-Wundeclared-selector"

Sie können diese Zeile in die .m-Datei einfügen, in der die Warnung auftritt.

pdate:

Es funktioniert auch mit LLVM wie folgt:

#pragma clang diagnostic Push
#pragma clang diagnostic ignored "-Wundeclared-selector"

... your code here ...

#pragma clang diagnostic pop
247
Klaas

Schauen Sie sich NSSelectorFromString an.

 SEL selector = NSSelectorFromString(@"setError:");
 if ([self respondsToSelector:selector])

Damit können Sie zur Laufzeit einen Selektor erstellen, anstatt zur Kompilierungszeit über das @selector, und der Compiler hat keine Chance, sich zu beschweren.

191
sergio

Ich denke, das liegt daran, dass der Selektor aus irgendeinem Grund nicht bei der Laufzeit registriert ist.

Versuchen Sie, den Selektor mit sel_registerName() zu registrieren:

SEL setErrorSelector = sel_registerName("setError:");

if([self respondsToSelector:setErrorSelector]) {
   [self performSelector:setErrorSelector withObject:[NSError errorWithDomain:@"SomeDomain" code:1 userInfo:nil]];
}
52
Jacob Relkin

Mir ist klar, dass ich etwas spät dran bin, aber der Vollständigkeit halber können Sie diese Warnung mithilfe der Zielerstellungseinstellungen global deaktivieren.

Ändern Sie im Abschnitt "Apple LLVM-Warnungen - Objective-C" Folgendes:

Undeclared Selector - NO
7
Quixiote

Ich habe diese Meldung erhalten, indem ich die Datei mit der Methode einbinde. Aus dieser Datei wurde nichts anderes verwendet.

7
Mark Patterson

Wenn Ihre Klasse die Methode setError: implementiert (auch wenn Sie den Setter der Eigenschaft eventual error als dynamisch deklarieren), möchten Sie diese möglicherweise in Ihrer Schnittstellendatei (.h) deklarieren, oder wenn Sie sie nicht so anzeigen möchten, wie Sie es könnten versuche es mit dem kniffligen PrivateMethods-Trick:

@interface Yourclass (PrivateMethods)

- (void) yourMethod1;
- (void) yourMethod2;

@end

kurz vor deiner @implementierung sollte dies die Warnungen verbergen;).

5
i_mush

Ein wirklich komfortables Makro, um es in Ihr .pch oder Common.h oder wo immer Sie wollen:

#define SUPPRESS_UNDECLARED_SELECTOR_LEAK_WARNING(code)                        \
_Pragma("clang diagnostic Push")                                        \
_Pragma("clang diagnostic ignored \"-Wundeclared-selector"\"")     \
code;                                                                   \
_Pragma("clang diagnostic pop")                                         \

Es ist eine Bearbeitung von diese Frage für ein ähnliches Problem ...

3
Aviel Gross

Eine andere Möglichkeit, diese Warnung zu vermeiden, besteht darin, sicherzustellen, dass Ihre Auswahlmethode folgendermaßen aussieht:

-(void) myMethod :(id) sender{
}

Vergessen Sie nicht "(id) sender", wenn Sie einen Absender akzeptieren möchten oder wenn Sie einen Typ eines Absenderobjekts angeben möchten.

2
Repose

Sie können es in Xcode wie im Screenshot deaktivieren:

enter image description here

2
SmallChess

Sie können das betreffende Objekt auch zuerst in eine ID umwandeln, um die Warnung zu vermeiden:

if ([object respondsToSelector:@selector(myMethod)]) {
    [(id)object myMethod];
}
1
Swindler

Während die richtige Antwort wahrscheinlich darin besteht, Xcode durch Importe zu informieren oder den Selektor zu registrieren, dass ein solcher Selektor existiert, fehlte mir in meinem Fall ein Semikolon. Stellen Sie sicher, bevor Sie den Fehler "beheben", dass der Fehler möglicherweise korrekt ist und Ihr Code nicht. Ich habe den Fehler beispielsweise im MVCNetworking-Beispiel von Apple gefunden.

0
Louis St-Amour