Ich habe gegoogelt, konnte aber nicht herausfinden, was das schnelle Äquivalent respondsToSelector:
ist.
Dies ist das einzige, was ich finden konnte ( schnelle Alternative zu responsondsToSelector :), aber in meinem Fall nicht allzu relevant, da es die Existenz des Delegaten überprüft. Ich habe keinen Delegaten, den ich nur überprüfen möchte, ob eine neue API vorhanden ist oder nicht, wenn auf dem Gerät ausgeführt wird und wenn nicht auf eine frühere Version der API zurückgegriffen wird.
objective-c
swift
selector
Gruntcakes
quelle
quelle
NSClassFromString
undrespondsToSelector
unter anderem Mechanik für die Überprüfung für neu implementierte Funktionalität, ich habe zu glauben , dass die Mechanismen , entweder an Ort und Stelle sind bereits oder wird es vor der Freigabe. Versuchen Sie, dasAdvanced Interop...
Video von WWDC anzusehen.if #available(...)
in Swift 2.x verwenden, um die Verwendung überhaupt zu vermeidenrespondsToSelector
. Aber das wusstest du. ( apple.co/1SNGtMQ )Antworten:
Wie bereits erwähnt, können Sie in Swift die meiste Zeit mit dem
?
optionalen Unrapper-Operator das erreichen, was Sie benötigen . Auf diese Weise können Sie eine Methode für ein Objekt genau dann aufrufen, wenn das Objekt vorhanden ist (nichtnil
) und die Methode implementiert ist.Falls Sie es noch benötigen
respondsToSelector:
, ist es als Teil desNSObject
Protokolls noch vorhanden.Wenn Sie
respondsToSelector:
in Swift einen Obj-C-Typ aufrufen , funktioniert dies genauso, wie Sie es erwarten würden. Wenn Sie es in Ihrer eigenen Swift-Klasse verwenden, müssen Sie sicherstellen, dass Ihre Klasse von abgeleitet istNSObject
.Hier ist ein Beispiel für eine Swift-Klasse, mit der Sie überprüfen können, ob sie auf einen Selektor reagiert:
Es ist wichtig, dass Sie die Parameternamen nicht auslassen. In diesem Beispiel
Selector("sleep::")
ist nicht dasselbe wieSelector("sleep:minutes:")
.quelle
let x =
Teil entfernen . Grundsätzlich besteht dieif let x = y
Struktur darin, optionale Werte (ähnlich wie!
) zu entpacken . Da Sie eineBool
Rückmeldung erhaltenrespondsToSelector
, beschwert sich der Compiler, dass das Ergebnis kein optionaler Typ ist (Bool?
).var
s deklariert passieren ? Reagieren sie immer noch genauso? In Objective-C könnte ichif ( [obj respondsToSelector:@selector(setSomeVar:)] ) { ... }
für einesomeVar
Immobilie tun . Funktioniert es genauso mitvar
s in Swift?Es gibt keinen echten Swift-Ersatz.
Sie können folgendermaßen prüfen:
Dies ruft die Methode
someMethod
nur auf, wenn sie für ein Objekt definiert ist.someObject
Sie können sie jedoch nur für@objc
Protokolle verwenden, die die Methode als deklariert habenoptional
.Swift ist von Natur aus eine sichere Sprache. Jedes Mal, wenn Sie eine Methode aufrufen, muss Swift wissen, dass die Methode vorhanden ist. Eine Laufzeitprüfung ist nicht möglich. Sie können nicht einfach zufällige Methoden für zufällige Objekte aufrufen.
Selbst in Obj-C sollten Sie solche Dinge nach Möglichkeit vermeiden, da sie mit ARC nicht gut funktionieren (ARC löst dann Warnungen für aus
performSelector:
).Wenn Sie jedoch nach verfügbaren APIs suchen, können Sie
respondsToSelector:
auch dann noch Swift verwenden, wenn Sie mitNSObject
Instanzen arbeiten:quelle
respondsToSelector:
da Apples Empfehlung ausdrücklich lautet, dass du es tun sollst. Siehe hierrespondsToSelector:
es wirklich gut ist, sie zu haben. Wenn Sie jedoch die Swift-Referenz durchgehen, wird über die Verwendung von Unterklassen für verschiedene Systemversionen gesprochen.if #available(iOS 10) {
und rufen die Methode dann direkt auf.Update 20. März 2017 für Swift 3-Syntax:
Wenn es Ihnen egal ist, ob die optionale Methode vorhanden ist, rufen Sie einfach auf
delegate?.optionalMethod?()
Ansonsten ist die Verwendung
guard
wahrscheinlich der beste Ansatz:Ursprüngliche Antwort:
Sie können den "if let" -Ansatz verwenden, um ein optionales Protokoll wie das folgende zu testen:
quelle
let theMethod = delegate.userNotificationCenter(_:willPresent:withCompletionHandler:)
Es scheint, dass Sie Ihr Protokoll als Unterprotokoll von NSObjectProtocol definieren müssen ... dann erhalten Sie die Methode respondsToSelector
Beachten Sie, dass es nicht ausreicht, nur @objc anzugeben. Sie sollten auch darauf achten, dass der eigentliche Delegat eine Unterklasse von NSObject ist - was in Swift möglicherweise nicht der Fall ist.
quelle
Wenn die Methode, auf die Sie testen, als optionale Methode in einem @ objc- Protokoll definiert ist (was wie Ihr Fall klingt), verwenden Sie das optionale Verkettungsmuster wie folgt:
Wenn die Methode als zurückgegeben deklariert wird
Void
, verwenden Sie einfach:Sehen:
quelle
if object.method?(args) { ... }
- der Aufruf der Methode, wenn es existiert, wird zurückkehren,Void
was nicht istnil
object
einen Typ hatAnyObject
, können Sie eine beliebige @ objc-Methode testen.Funktionen sind in Swift erstklassige Typen. Sie können also überprüfen, ob eine in einem Protokoll definierte optionale Funktion implementiert wurde, indem Sie sie mit nil vergleichen:
quelle
Für swift3
Wenn Sie nur die Methode aufrufen möchten, führen Sie den folgenden Code aus.
self.delegate?.method?()
quelle
In Swift 2 hat Apple eine neue Funktion namens "eingeführt"
API availability checking
, die möglicherweise dierespondsToSelector:
Methode ersetzt. Der folgende Code-Snippet-Vergleich wurde aus der WWDC2015-Sitzung 106 " Was ist neu in Swift" kopiert, von der ich dachte, dass sie Ihnen helfen könnte mehr wissen.quelle
respondsToSelector
Ansatz in Swift. Dies liegt auch daran, dass die Auswahlprüfung nicht die beste Lösung für dieses Problem war (Verfügbarkeitsprüfung).Für schnelle 3.0
quelle
Derzeit (Swift 2.1) können Sie dies auf drei Arten überprüfen:
Verwenden von '?' beantwortet von @Sulthan
Und mit
as?
Operator:Grundsätzlich hängt es davon ab, was Sie erreichen möchten:
quelle
Ich implementiere dies einfach selbst in einem Projekt, siehe Code unten. Wie von @Christopher Pickslay erwähnt, ist es wichtig zu bedenken, dass Funktionen erstklassige Bürger sind und daher wie optionale Variablen behandelt werden können.
quelle
eine andere mögliche Syntax von Swift ..
quelle
Als ich anfing, mein altes Projekt auf Swift 3.2 zu aktualisieren, musste ich nur die Methode von ändern
zu:
quelle
Ich benutze
guard let else
, damit das einige Standard-Sachen machen kann, wenn die Delegatenfunktion nicht implementiert ist.quelle
Swift 3:
Protokoll
Objekt
quelle
Das Äquivalent ist das? Operator:
ImportantMethod wird nur aufgerufen, wenn myQuestionableObject vorhanden ist und es implementiert.
quelle
?
nachimportantMethod