Muito tempo em meus projetos ao escrever quando usei o tipo
Qualquer , por exemplo, ao processar dados JSON. Mas também sabia que existe um segundo tipo -
AnyObject . E, recentemente, tenho pensado na diferença entre esses dois tipos.
De acordo com a documentação da Apple:
- Qualquer - pode representar uma instância de qualquer tipo
- AnyObject - pode representar uma instância de qualquer classe
Para simplificar um pouco, então:
- Qualquer um é usado para todos os tipos.
- AnyObject - usado para tipos de classe
Vamos verificar na prática esses dois tipos. Vamos começar com o tipo
Qualquer .
Para fazer isso, crie uma matriz do tipo Qualquer e imprima-a.
let anyArray: [Any] = ["Macbook", 1, 2] print(anyArray) Console: ["Macbook", 1, 2]
Como podemos ver, Any permite que você trabalhe com diferentes tipos de dados ao mesmo tempo (String, Int).
De acordo com a documentação, os elementos (
String e
Int ) nessa matriz são estruturas que são tipos de valor; portanto, teoricamente,
AnyObject não deve funcionar.
Para verificar isso, crie uma matriz idêntica do tipo
AnyObject .
let anyObjectArray: [AnyObject] = ["Macbook", 1, 2]
Como esperado, o compilador nos fornece um erro sobre a impossibilidade de converter o tipo "String / Int" para o tipo
AnyObjectErro do compiladorNão é possível converter o valor do tipo "Int" para o tipo de elemento esperado "AnyObject"
Não é possível converter o valor do tipo "Int" para o tipo de elemento esperado "AnyObject"
Não é possível converter o valor do tipo "String" para o tipo de elemento esperado "AnyObject"
Mas vamos tentar trazer nossos três tipos para o AnyObject e imprimir o resultado.
let anyObjectArray: [AnyObject] = ["Macbook" as AnyObject, 1 as AnyObject, 2 as AnyObject] print(anyObjectArray) Console: [Macbook, 1, 2]
O erro do compilador desapareceu. Como podemos ver, uma string do
Macbook claramente se parece com uma string, mas não possui as aspas usuais, como o tipo
String no Swift.
Vamos tentar imprimir a matriz usando um loop para verificar seu 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
Uma string é do tipo String. Como dito anteriormente, as strings no Swift são estruturas, não tipos de classes. Portanto, não devemos poder usá-los como AnyObject.
Vamos realizar mais algumas experiências com nossa matriz. Vamos tentar verificá-los para os tipos de Objective-C:
NSString e
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
Então, por que isso está acontecendo?
Como parte de sua compatibilidade com o Objective-C, o Swift oferece maneiras convenientes e eficientes de trabalhar com plataformas de cacau.
O Swift converterá automaticamente alguns tipos de Objective-C em tipos Swift e alguns tipos de Swift em tipos de Objective-C. Tipos que podem ser convertidos entre Objective-C e Swift são chamados
concatenados .
Em outras palavras, o compilador faz todo o possível para ser flexível no manuseio desses tipos, convertendo e criando automaticamente "pontes", ao mesmo tempo em que evita falhas no aplicativo.
Quando usar o AnyObject?
Conforme declarado na documentação da Apple, o AnyObject pode ser usado para trabalhar com objetos
derivados da Classe, mas que não possuem uma classe raiz comum.
No Swift 3, o tipo de identificação no Objective-C agora está mapeado para o tipo Any no Swift, que descreve o valor de qualquer tipo, seja uma classe, enumeração, estrutura ou qualquer outro tipo Swift. Essa alteração torna as APIs do Objective-C mais flexíveis no Swift, porque os tipos de valores definidos pelo Swift podem ser passados para as APIs do Objective-C e recuperados como tipos do Swift, eliminando a necessidade de tipos manuais de "bloqueio".
Portanto,
é aconselhável usar o AnyObject quando desejar restringir o protocolo para que ele possa ser usado apenas com classes e
Any em outros casos .
A Apple acrescenta :
Use
Any e
AnyObject somente quando precisar explicitamente do comportamento e dos recursos que eles fornecem. É sempre melhor ser preciso sobre os tipos que você espera usar no seu código.