Swift 3 – Cómo verificar el tipo de clase de objeto

Esta línea de código solía funcionar con Swift 2, pero ahora es incorrecta en Swift 3.

if gestureRecognizer.isMember(of: UITapGestureRecognizer) { } 

Obtengo este error: Nombre de miembro esperado o llamada de constructor después del nombre de tipo.

¿Cuál es la forma correcta de usar isMember(of:) ?

Lo más probable es que desees no solo verificar el tipo, sino también enviarlo a ese tipo. En este caso, use:

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

Operadores de fundición Swift

Estos operadores solo están disponibles en Swift, pero aún funcionan cuando se trata de tipos de Objective C.

  • El operador as

    • El operador as realiza un lanzamiento cuando se sabe en el momento de la comstackción que el lanzamiento siempre tiene éxito, como la difusión ascendente o el puente. Upcasting le permite usar una expresión como una instancia del supertipo de su tipo, sin usar una variable intermedia.

    • Este es el operador más preferible para usar, cuando sea posible. Garantiza el éxito, sin preocuparse de desenvolver un accidente opcional o arriesgarse.
  • as? operador

    • as? el operador realiza un molde condicional de la expresión al tipo especificado. as? operador devuelve un opcional del tipo especificado. En tiempo de ejecución, si el elenco tiene éxito, el valor de la expresión se ajusta de forma opcional y se devuelve; de lo contrario, el valor devuelto es nil . Si se garantiza que el lanzamiento al tipo especificado falla o se garantiza que tendrá éxito, se genera un error de tiempo de comstackción.

    • Este es el segundo operador más preferible para usar. Úselo para manejar de forma segura el caso en el que no se puede realizar un operador de casting.

  • ¡El as! operador

    • ¡El as! el operador realiza un lanzamiento forzado de la expresión al tipo especificado. ¡El as! el operador devuelve un valor del tipo especificado, no un tipo opcional. Si el molde falla, se genera un error de tiempo de ejecución. El comportamiento de x as! T x as! T es lo mismo que el comportamiento de (x as? T)! .

    • Este es el operador menos preferido para usar. Recomiendo encarecidamente no abusar de él. Intentar lanzar una expresión a un tipo incompatible bloquea su progtwig.


Swift tipo de comprobación

Si simplemente desea verificar el tipo de expresión, sin conversión a ese tipo, puede utilizar estos enfoques. Solo están disponibles en Swift, pero aún funcionan cuando se trata de tipos de Objective C.

  • El operador is

    • El operador is verifica en tiempo de ejecución si la expresión puede convertirse al tipo especificado. Devuelve true si la expresión se puede convertir al tipo especificado; de lo contrario, devuelve false
    • Funciona en cualquier tipo de Swift, incluidos los tipos de Objective C.
    • Swift equivalente de isKind(of:)
  • Usando el type(of:)

    • A diferencia del operador is , esto se puede usar para verificar el tipo exacto, sin considerar las subclases.
    • Se puede usar como: type(of: instance) == DesiredType.self
    • Swift equivalente de isMember(of:)

Métodos heredados (objective C) para verificar tipos

Estos son todos los métodos en NSObjectProtocol . Se pueden usar en el código Swift, pero solo aplican el trabajo con clases derivadas de NSObjectProtocol (como las subclases de NSObject ). Aconsejo no usar estos, pero los menciono aquí para completar

  • isKind(of:)

    • Devuelve un valor booleano que indica si el receptor es una instancia de una clase dada o una instancia de cualquier clase que hereda de esa clase
    • Evita esto en Swift, use is operator en su lugar.
  • isMember(of:)

    • Devuelve un valor booleano que indica si el receptor es una instancia de una clase determinada
    • Es un método en NSObjectProtocol , por lo tanto, solo funciona en clases que se derivan de NSObjectProtocol (como las subclases de NSObject )
    • Evita esto en Swift, usa type(of: instance) == DesiredType.self en type(of: instance) == DesiredType.self lugar.
  • conforms(to:)

    • Devuelve un valor booleano que indica si el receptor se ajusta a un protocolo determinado.
    • Es un método en NSObjectProtocol , por lo tanto, solo funciona en clases que se derivan de NSObjectProtocol (como las subclases de NSObject )
    • Evita esto en Swift, use is operator en su lugar.

Hay varias formas de verificar la clase de un objeto. La mayoría de las veces, ¿querrá usar ya sea el is o el as? los operadores así:

 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") } 

Tienes que usar .self para referir el tipo de clase ahora.

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

También hay:

 print (a is UITapGestureRecognizer) 

Swift 3:

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