web-dev-qa-db-fra.com

Swift 3 - Comment vérifier le type de classe d'un objet

Cette ligne de code fonctionnait avec Swift 2, mais est maintenant incorrect dans Swift 3.

if gestureRecognizer.isMember(of: UITapGestureRecognizer) { }

Je reçois cette erreur: nom du membre attendu ou appel du constructeur après le nom du type.

Quelle est la bonne façon d'utiliser isMember(of:)?

33
Van Du Tran

Très probablement, vous voudrez non seulement vérifier le type, mais également attribuer à ce type. Dans ce cas, utilisez:

if let gestureRecognizer as? UITapGestureRecognizer { }
else { /* not a UITapGestureRecognizer */ }

Opérateurs de casting rapides

Ces opérateurs ne sont disponibles que dans Swift, mais fonctionnent quand même avec les types Objective C.

  • L'opérateur as

    • L'opérateur as effectue une conversion lorsqu'il est connu, au moment de la compilation, que l'opération réussit toujours, telle que la conversion ascendante ou le pontage. La diffusion en amont vous permet d’utiliser une expression en tant qu’instance du sur-type de son type, sans utiliser de variable intermédiaire.

    • C'est l'opérateur le plus préférable à utiliser, lorsque cela est possible. Il garantit le succès, sans se soucier de déballer une option ou de risquer un crash.
  • L'opérateur as?

    • L'opérateur as? Effectue une conversion conditionnelle de l'expression vers le type spécifié. L'opérateur as? Renvoie une option du type spécifié. Au moment de l'exécution, si la conversion réussit, la valeur de expression est facultative et renvoyée. sinon, la valeur renvoyée est nil. Si le transtypage vers le type spécifié échoue ou réussit, une erreur de compilation est générée.

    • C'est le deuxième opérateur le plus préférable à utiliser. Utilisez-le pour gérer en toute sécurité le cas dans lequel un opérateur de casting ne peut pas être effectué.

  • L'opérateur as!

    • L'opérateur as! Effectue une conversion forcée de l'expression dans le type spécifié. L'opérateur as! Renvoie une valeur du type spécifié, pas un type facultatif. Si la conversion échoue, une erreur d'exécution est générée. Le comportement de x as! T Est identique à celui de (x as? T)!.

    • C'est l'opérateur le moins préférable à utiliser. Je déconseille fortement d'en abuser. Tenter de convertir une expression en un type incompatible bloque votre programme.


Vérification de type rapide

Si vous voulez simplement vérifier le type d'une expression, sans transtyper ce type, vous pouvez utiliser ces approches. Ils ne sont disponibles que dans Swift, mais fonctionnent quand même avec les types Objective C.

  • L'opérateur is

    • L'opérateur is vérifie au moment de l'exécution si l'expression peut être transtypée vers le type spécifié. Il retourne true si l'expression peut être convertie dans le type spécifié. sinon, il retourne false
    • Fonctionne sur tout type Swift, y compris les types Objective C).
    • Équivalent Swift de isKind(of:)
  • Utilisation de type(of:)

    • Contrairement à l'opérateur is, il peut être utilisé pour vérifier le type exact, sans considération pour les sous-classes.
    • Peut être utilisé comme: type(of: instance) == DesiredType.self
    • Équivalent Swift de isMember(of:)

Méthodes Legacy (Objective C) pour la vérification des types

Ce sont toutes des méthodes sur NSObjectProtocol . Ils peuvent être utilisés dans le code Swift, mais ), ils s’appliquent uniquement aux classes dérivées de NSObjectProtocol (comme les sous-classes de NSObject). Je vous déconseille de les utiliser, mais je les mentionne ici par souci d'exhaustivité.

  • isKind(of:)

    • Renvoie une valeur booléenne indiquant si le destinataire est une instance d'une classe donnée ou une instance d'une classe quelconque qui hérite de cette classe .
    • Évitez cela dans Swift, utilisez plutôt l'opérateur is.
  • isMember(of:)

    • Renvoie une valeur booléenne indiquant si le destinataire est une instance d'une classe donnée.
    • Est une méthode sur NSObjectProtocol , ne fonctionne donc que sur les classes dérivées de NSObjectProtocol (telles que les sous-classes de NSObject)
    • Évitez cela dans Swift, utilisez plutôt type(of: instance) == DesiredType.self.
  • conforms(to:)

    • Renvoie une valeur booléenne indiquant si le récepteur est conforme à un protocole donné.
    • Est une méthode sur NSObjectProtocol , ne fonctionne donc que sur les classes dérivées de NSObjectProtocol (telles que les sous-classes de NSObject)
    • Évitez cela dans Swift, utilisez plutôt l'opérateur is.
117
Alexander

Il existe plusieurs façons de vérifier la classe d'un objet. La plupart du temps, vous voudrez utiliser soit le is, soit le as? opérateurs comme ça:

let gestureRecognizer: UIGestureRecognizer = UITapGestureRecognizer()

// Using the is operator
if gestureRecognizer is UITapGestureRecognizer {
    // You know that the object is an instance of UITapGestureRecognizer,
    // but the compiler will not let you use UITapGestureRecognizer specific
    // methods or properties on gestureRecognizer because the type of the
    // variable is still UIGestureRecognizer
    print("Here")
}

// Using the as? operator and optional binding
if let tapGestureRecognizer = gestureRecognizer as? UITapGestureRecognizer {
    // tapGestureRecognizer is the same object as gestureRecognizer and is
    // of type UITapGestureRecognizer, you can use UITapGestureRecognizer
    // specific methods or properties.
    print("Here")
}

// Using the type(of:) global function
if type(of: gestureRecognizer) == UITapGestureRecognizer.self {
    // gestureRecognizer is an instance of UITapGestureRecognizer, but not any
    // of its subclasses (if gestureRecognizer was an instance of a subclass of
    // UITapGestureRecognizer, the body of this if would not execute).
    // This kind of check is rarely usefull, be sure this is really what you
    // want to do before you use it.
    print("Here")
}

// Using the isKind(of:) method
if gestureRecognizer.isKind(of: UITapGestureRecognizer.self) {
    // Like for the is operator, you know that the object is an instance of
    // UITapGestureRecognizer (or any subclass of UITapGestureRecognizer).
    // This is the Objective-C version of the is operator and will only work
    // on classes that inherit from NSObject, don't use it in Swift.
    print("Here")
}

// Using the isMember(of:) method
if gestureRecognizer.isMember(of: UITapGestureRecognizer.self) {
    // gestureRecognizer is an instance of UITapGestureRecognizer, but not
    // any of its subclasses.
    // This is the Objective-C version of type(of:) and will only work on
    // classes that inherit from NSObject, don't use it in Swift.
    print("Here")
}
20
deadbeef

Vous devez utiliser .self pour faire référence au type de classe maintenant.

let a = UITapGestureRecognizer()
print (a.isMember(of: UIGestureRecognizer.self))

Il y a aussi:

print (a is UITapGestureRecognizer)
5
Josh Homann

Swift 3:

if gestureRecognizer is UITapGestureRecognizer {
            //It's a tap
}
3
Zigglzworth