Mucho tiempo en mis proyectos cuando escribía cuando usaba
Any type, por ejemplo, cuando procesaba datos JSON. Pero también sabía que hay un segundo tipo:
AnyObject . Y recientemente, he estado pensando en la diferencia entre estos dos tipos.
De acuerdo con la documentación de Apple:
- Cualquiera : puede representar una instancia de cualquier tipo
- AnyObject : puede representar una instancia de cualquier clase
Para decirlo un poco más fácil, entonces:
- Cualquiera se usa para todos los tipos.
- AnyObject : se usa para los tipos de clase
Verifiquemos en la práctica estos dos tipos. Comencemos con el tipo
Any .
Para hacer esto, cree una matriz de tipo Any e imprímala.
let anyArray: [Any] = ["Macbook", 1, 2] print(anyArray) Console: ["Macbook", 1, 2]
Como podemos ver, Any le permite trabajar con diferentes tipos de datos al mismo tiempo (String, Int).
De acuerdo con la documentación, los elementos (
String e
Int ) en esta matriz son estructuras que son tipos de valores, por lo tanto, en teoría,
AnyObject no debería funcionar.
Para verificar esto, cree una matriz idéntica de tipo
AnyObject .
let anyObjectArray: [AnyObject] = ["Macbook", 1, 2]
Como se esperaba, el compilador nos da un error sobre la imposibilidad de convertir el tipo "String / Int" al tipo
AnyObjectError del compiladorNo se puede convertir el valor del tipo "Int" al tipo de elemento esperado "AnyObject"
No se puede convertir el valor del tipo "Int" al tipo de elemento esperado "AnyObject"
No se puede convertir el valor del tipo "Cadena" al tipo de elemento esperado "AnyObject"
Pero intentemos llevar nuestros tres tipos a AnyObject e imprimir el resultado.
let anyObjectArray: [AnyObject] = ["Macbook" as AnyObject, 1 as AnyObject, 2 as AnyObject] print(anyObjectArray) Console: [Macbook, 1, 2]
El error del compilador ha desaparecido. Como podemos ver, una cadena de
Macbook se ve claramente como una cadena, pero no tiene las comillas habituales como el tipo de
cadena en Swift.
Intentemos imprimir la matriz usando un bucle para verificar su tipo real.
for item in anyObjectArray { if item is String { print("\(item) String") } else if item is Int { print("\(item) Int") } } Console: Macbook String 1 Int 2 Int
Una cadena es de tipo cadena. Como se dijo antes, las cadenas en Swift son estructuras, no tipos de clases. Por lo tanto, no deberíamos poder usarlos como AnyObject.
Realicemos un par de experimentos más con nuestra matriz. Intentemos verificar si hay tipos de Objective - C:
NSString y
NSNumber .
for item in anyObjectArray { if item is NSString { print("\(item) NSString") } else if item is NSNumber { print("\(item) NSNumber") } } Console: Macbook NSString 1 NSNumber 2 NSNumber
Entonces, ¿por qué está pasando esto?
Como parte de su compatibilidad con Objective - C, Swift ofrece formas convenientes y eficientes de trabajar con las plataformas Cocoa.
Swift convertirá automáticamente algunos tipos de Objective - C a tipos de Swift, y algunos tipos de Swift a tipos de Objective - C. Los tipos que se pueden convertir entre Objetivo - C y Swift se denominan
concatenados .
En otras palabras, el compilador hace todo lo posible para ser flexible en el manejo de estos tipos al convertir y crear automáticamente "puentes", al mismo tiempo que evita los bloqueos de la aplicación.
¿Cuándo usar AnyObject?
Como se indica en la documentación de Apple, AnyObject se puede utilizar para trabajar con objetos
derivados de Class pero que no tienen una clase raíz común.
En Swift 3, el tipo de identificación en Objetivo - C ahora se asigna a Cualquier tipo en Swift, que describe el valor de cualquier tipo, ya sea una clase, enumeración, estructura o cualquier otro tipo de Swift. Este cambio hace que las API de Objective - C sean más flexibles en Swift, porque los tipos de valor definidos por Swift pueden pasarse a las API de Objective - C y recuperarse como tipos de Swift, eliminando la necesidad de tipos de "bloques" manuales.
Por
lo tanto,
es aconsejable usar AnyObject cuando desee restringir el protocolo para que pueda usarse solo con clases y
Any en otros casos .
Apple agrega :
Use
Any y
AnyObject solo cuando necesite explícitamente el comportamiento y las capacidades que proporcionan. Siempre es mejor ser preciso sobre los tipos que espera usar en su código.