J'ai fait une recherche sur Google, mais je n'ai pas pu découvrir à quoi correspond l'équivalent rapide respondsToSelector:
.
C'est la seule chose que j'ai pu trouver ( alternative Swift à respondsToSelector:) mais n'est pas trop pertinente dans mon cas car elle vérifie l'existence du délégué, je n'ai pas de délégué, je veux juste vérifier si une nouvelle API existe ou non lors de l'exécution sur l'appareil et sinon revenir à une version précédente de l'API.
objective-c
swift
selector
Gruntcakes
la source
la source
NSClassFromString
etrespondsToSelector
entre autres mécanismes pour vérifier les fonctionnalités nouvellement implémentées, je dois croire que les mécanismes sont déjà en place ou seront là avant la sortie. Essayez de regarder laAdvanced Interop...
vidéo de la WWDC.if #available(...)
dans Swift 2.x pour éviter de l'utiliserrespondsToSelector
en premier lieu. Mais tu le savais. ( apple.co/1SNGtMQ )Réponses:
Comme mentionné, dans Swift la plupart du temps, vous pouvez obtenir ce dont vous avez besoin avec l'
?
opérateur de déballage en option . Cela vous permet d'appeler une méthode sur un objet si et seulement si l'objet existe (pasnil
) et que la méthode est implémentée.Dans le cas où vous en avez encore besoin
respondsToSelector:
, il est toujours là dans le cadre duNSObject
protocole.Si vous appelez
respondsToSelector:
un type Obj-C dans Swift, cela fonctionne de la même manière que vous vous attendez. Si vous l'utilisez dans votre propre classe Swift, vous devrez vous assurer que votre classe dériveNSObject
.Voici un exemple de classe Swift que vous pouvez vérifier si elle répond à un sélecteur:
Il est important de ne pas omettre les noms de paramètres. Dans cet exemple,
Selector("sleep::")
n'est pas identique àSelector("sleep:minutes:")
.la source
let x =
partie. Fondamentalement, laif let x = y
structure consiste à dérouler les valeurs facultatives (similaires à!
). Puisque vous obtenez unBool
retour derespondsToSelector
, le compilateur se plaint que le résultat n'est pas un type facultatif (Bool?
).var
s déclarés? Répondent-ils toujours de la même manière? En Objective-C je pourrais faireif ( [obj respondsToSelector:@selector(setSomeVar:)] ) { ... }
pour unesomeVar
propriété. Cela fonctionne-t-il de la même manière avecvar
s dans Swift?Il n'y a pas de véritable remplacement Swift.
Vous pouvez vérifier de la manière suivante:
Cela appelle la méthode
someMethod
uniquement si elle est définie sur l'objetsomeObject
mais vous ne pouvez l'utiliser que pour les@objc
protocoles qui ont déclaré la méthode commeoptional
.Swift est intrinsèquement un langage sûr, donc chaque fois que vous appelez une méthode, Swift doit savoir que la méthode est là. Aucune vérification d'exécution n'est possible. Vous ne pouvez pas simplement appeler des méthodes aléatoires sur des objets aléatoires.
Même dans Obj-C, vous devriez éviter de telles choses lorsque cela est possible car il ne fonctionne pas bien avec ARC (ARC déclenche alors des avertissements pour
performSelector:
).Cependant, lors de la vérification des API disponibles, vous pouvez toujours utiliser
respondsToSelector:
, même si Swift, si vous avez affaire à desNSObject
instances:la source
respondsToSelector:
car la recommandation d'Apple est explicitement que vous devriez le faire. Voir icirespondsToSelector:
c'est vraiment bien d'avoir. Mais si vous passez par la référence Swift, ils parlent d'utiliser des sous-classes pour différentes versions du système.if #available(iOS 10) {
, puis appelons directement la méthode.Mise à jour du 20 mars 2017 pour la syntaxe Swift 3:
Si vous ne vous souciez pas de savoir si la méthode facultative existe, appelez simplement
delegate?.optionalMethod?()
Sinon, l'utilisation
guard
est probablement la meilleure approche:Réponse originale:
Vous pouvez utiliser l'approche "if let" pour tester un protocole facultatif comme celui-ci:
la source
let theMethod = delegate.userNotificationCenter(_:willPresent:withCompletionHandler:)
Il semble que vous deviez définir votre protocole comme un sous-protocole de NSObjectProtocol ... alors vous obtiendrez la méthode respondsToSelector
notez que la seule spécification de @objc n'était pas suffisante. Vous devez également faire attention à ce que le délégué réel soit une sous-classe de NSObject - ce qui dans Swift ne l'est peut-être pas.
la source
Si la méthode que vous testez est définie comme une méthode facultative dans un protocole @objc (qui ressemble à votre cas), utilisez le modèle de chaînage facultatif comme suit :
Lorsque la méthode est déclarée comme retournant
Void
, utilisez simplement:Voir:
la source
if object.method?(args) { ... }
- l'appel de la méthode, lorsqu'elle existe, reviendra,Void
ce qui n'est pas le casnil
object
est de typeAnyObject
, vous pouvez tester n'importe quelle méthode @objc.Les fonctions sont des types de première classe dans Swift, vous pouvez donc vérifier si une fonction facultative définie dans un protocole a été implémentée en la comparant à nil:
la source
Pour swift3
Si vous souhaitez simplement appeler la méthode, exécutez le code ci-dessous.
self.delegate?.method?()
la source
Dans Swift 2, Apple a introduit une nouvelle fonctionnalité appelée
API availability checking
, qui pourrait remplacer larespondsToSelector:
méthode.La comparaison d' extraits de code suivante est copiée à partir de la session 106 de la WWDC2015 Quoi de neuf dans Swift qui, à mon avis, pourrait vous aider, veuillez la vérifier si vous en avez besoin savoir plus.la source
respondsToSelector
approche dans Swift. C'est aussi parce que la vérification du sélecteur n'était pas la meilleure solution à ce problème (vérification de la disponibilité) en premier lieu.Pour swift 3.0
la source
Actuellement (Swift 2.1), vous pouvez le vérifier de 3 manières:
Utiliser "?" répondu par @Sulthan
Et en utilisant l'
as?
opérateur:Fondamentalement, cela dépend de ce que vous essayez de réaliser:
la source
Je viens de l'implémenter moi-même dans un projet, voir le code ci-dessous. Comme le mentionne @Christopher Pickslay, il est important de se rappeler que les fonctions sont des citoyens de première classe et peuvent donc être traitées comme des variables facultatives.
la source
une autre syntaxe possible par swift ..
la source
Comme j'ai commencé à mettre à jour mon ancien projet vers Swift 3.2, je devais juste changer la méthode de
à:
la source
J'utilise
guard let else
, donc cela peut faire des trucs par défaut si le func délégué n'est pas implémenté.la source
Swift 3:
protocole
Objet
la source
L'équivalent est le? opérateur:
importantMethod ne sera appelé que si myQuestionableObject existe et l'implémente.
la source
?
aprèsimportantMethod