ios - mega - Swift 3-Cómo verificar el tipo de clase de objeto
inicializadores swift (4)
Esta línea de código solía funcionar con Swift 2, pero ahora es incorrecta en Swift 3.
if gestureRecognizer.isMember(of: UITapGestureRecognizer) { }
Recibo 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:)
?
Hay varias formas de verificar la clase de un objeto.
¿La mayoría de las veces querrás usar ya sea el
is
o el
as?
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")
}
Lo más probable es que desee no solo verificar el tipo, sino también transmitir a ese tipo. En este caso, use:
if let gestureRecognizer as? UITapGestureRecognizer { }
else { /* not a UITapGestureRecognizer */ }
Operadores de casting rápidos
Estos operadores solo están disponibles en Swift, pero aún funcionan cuando se trata de tipos de Objetivo C.
-
El
as
operador-
El operador
as
realiza un lanzamiento cuando se sabe en el momento de la compilación que el lanzamiento siempre tiene éxito, como la conversió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 por desenvolver una opción o arriesgarse a un choque.
-
-
El as operador
-
El
as?
El operador realiza una conversión condicional de la expresión al tipo especificado. Elas?
El operador devuelve un opcional del tipo especificado. En tiempo de ejecución, si la conversión tiene éxito, el valor de la expresión se ajusta de forma opcional y se devuelve; de lo contrario, el valor devuelto esnil
. Si se garantiza que la conversión al tipo especificado falla o se garantiza que tiene éxito, se genera un error en tiempo de compilación. -
Este es el segundo operador más preferible para usar. Úselo para manejar con seguridad el caso en el que no se puede realizar un operador de lanzamiento.
-
-
El as operador
-
El
as!
El operador realiza una conversión forzada de la expresión al tipo especificado. Elas!
El operador devuelve un valor del tipo especificado, no un tipo opcional. Si el lanzamiento falla, se genera un error de tiempo de ejecución. El comportamiento dex as! T
x as! T
es igual al comportamiento de(x as? T)!
. -
Este es el operador menos preferible para usar. Recomiendo encarecidamente no abusar de él. Intentar emitir una expresión a un tipo incompatible bloquea su programa.
-
Comprobación de tipo rápida
Si simplemente desea verificar el tipo de una expresión, sin convertir a ese tipo, puede utilizar estos enfoques. Solo están disponibles en Swift, pero aún funcionan cuando se trata de tipos de Objetivo C.
-
El operador as
-
El operador
is
comprueba en tiempo de ejecución si la expresión se puede convertir al tipo especificado. Devuelvetrue
si la expresión se puede convertir al tipo especificado; de lo contrario, devuelvefalse
- Funciona en cualquier tipo Swift, incluidos los tipos de Objective C.
-
Equivalente rápido de
isKind(of:)
-
El operador
-
Usando
type(of:)
-
A diferencia del operador
is
, esto se puede utilizar para verificar el tipo exacto, sin tener en cuenta las subclases. -
Se puede usar como:
type(of: instance) == DesiredType.self
-
Equivalente rápido de
isMember(of:)
-
A diferencia del operador
Métodos heredados (Objetivo C) para verificar tipos
Todos estos son métodos en
NSObjectProtocol
.
Se pueden usar en el código Swift, pero
solo aplican el trabajo con clases que derivan de
NSObjectProtocol
(como las subclases de
NSObject
).
Aconsejo no usarlos, 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
- Evite esto en Swift, use el operador 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 que solo funciona en clases que derivan deNSObjectProtocol
(como las subclases deNSObject
) -
Evite esto en Swift, use
type(of: instance) == DesiredType.self
entype(of: instance) == DesiredType.self
lugar.
-
conforms(to:)
- Devuelve un valor booleano que indica si el receptor se ajusta a un protocolo dado.
-
Es un método en
NSObjectProtocol
, por lo que solo funciona en clases que derivan deNSObjectProtocol
(como las subclases deNSObject
) - Evite esto en Swift, use el operador en su lugar.
Swift 3:
if gestureRecognizer is UITapGestureRecognizer {
//It''s a tap
}
Tiene 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)