Ich möchte einen Selektor für eine NSObject-Instanz verwenden, ohne dass ein implementiertes Protokoll erforderlich ist. 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 und gibt mir daher eine Warnung für jede Zeile, die das @selector(setError:)
Snippet enthält :
Undeclared selector 'setError:'
Ich möchte kein Protokoll deklarieren müssen, um diese Warnung zu entfernen, da ich nicht möchte, dass alle Klassen, die dies verwenden, etwas Besonderes implementieren. Nur durch Konvention möchte ich, dass sie eine setError:
Methode oder Eigenschaft haben.
Ist das machbar? Wie?
Prost,
EP
quelle
Antworten:
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.
Aktualisieren:
Es funktioniert auch mit LLVM wie folgt:
#pragma clang diagnostic push #pragma clang diagnostic ignored "-Wundeclared-selector" ... your code here ... #pragma clang diagnostic pop
quelle
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"
// Do your thing
#pragma clang diagnostic pop
#pragma clang diagnostic ignored "-Wselector"
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
Schlüsselwort, und der Compiler hat keine Möglichkeit, sich zu beschweren.quelle
sel_registerName()
Ding sieht dunkel aus und die Art, die Sie nicht direkt anrufen sollten, wenn Sie nicht wissen, was Sie tun, wie obj_msg_send ();)Ich denke, das liegt daran, dass der Selektor aus irgendeinem Grund nicht zur Laufzeit registriert ist.
Versuchen Sie, den Selektor über Folgendes zu registrieren
sel_registerName()
:SEL setErrorSelector = sel_registerName("setError:"); if([self respondsToSelector:setErrorSelector]) { [self performSelector:setErrorSelector withObject:[NSError errorWithDomain:@"SomeDomain" code:1 userInfo:nil]]; }
quelle
NSSelectorFromString
ruftsel_registerName()
sowieso unter der Haube an. Wählen Sie, was besser zu Ihnen passt.sel_registerName()
direkter Anruf expliziter darüber ist, warum Sie das tun. sagt IhnenNSSelectorFromString
nicht , dass versucht wird, den Selektor zu registrieren.Ich habe diese Nachricht erhalten, indem ich die Datei mit der Methode eingeschlossen habe. Aus dieser Datei wurde nichts anderes verwendet.
quelle
Mir ist klar, dass ich zu spät zu diesem Thread komme, aber der Vollständigkeit halber können Sie diese Warnung mithilfe der Ziel-Build-Einstellungen global deaktivieren.
Im Abschnitt "Apple LLVM-Warnungen - Ziel-C" ändern Sie:
Undeclared Selector - NO
quelle
Wenn Ihre Klasse die setError: -Methode implementiert (auch wenn Sie den Setter der eventuellen Fehlereigenschaft dynamisch deklarieren), möchten Sie sie möglicherweise in Ihrer Schnittstellendatei (.h) deklarieren, oder wenn Sie sie nicht so anzeigen möchten, können Sie dies Versuchen Sie es mit dem kniffligen Trick von PrivateMethods:
@interface Yourclass (PrivateMethods) - (void) yourMethod1; - (void) yourMethod2; @end
kurz vor deiner @implementierung sollte dies die Warnungen verbergen;).
quelle
PerformSelector may cause a leak because its selector is unknown
Ein wirklich komfortables Makro, das Sie in Ihr
.pch
oderCommon.h
oder wo immer Sie möchten einfügen können:#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 dieser Frage für ein ähnliches Problem ...
quelle
Sie können es in Xcode wie im Screenshot deaktivieren:
quelle
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]; }
quelle
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) Absender", wenn Sie einen Absender akzeptieren oder einen Typ eines Absenderobjekts angeben möchten, wenn Sie dies bevorzugen.
quelle
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 zum Beispiel im MVCNetworking-Beispiel von Apple gefunden.
quelle
Ich konnte die Warnung durch Hinzufügen einer anderen Methode zum Verschwinden bringen (Offenlegung: Ich habe nicht daran gedacht, sondern sie gefunden, indem ich auf den geplanten Termin mit dem Intervall gegoogelt habe)
[NSTimer scheduledTimerWithTimeInterval:[[NSDate distantFuture] timeIntervalSinceNow] target:self selector:@selector(donothingatall:) userInfo:nil repeats:YES]; [[NSRunLoop currentRunLoop] run]; HTTPLogVerbose(@"%@: BonjourThread: Aborted", THIS_FILE); } } + (void) donothingatall:(NSTimer *)timer { }
Obwohl ich es zu schätzen weiß, wie man die Warnung verbirgt, ist es besser, sie zu beheben, und aus unbekannten Gründen haben weder Sergios noch Relkins Techniken für mich funktioniert.
quelle