Any et AnyObject dans Swift. Quelle est leur différence?

Assez longtemps dans mes projets lors de l'écriture lorsque j'ai utilisé le type Any , par exemple, lors du traitement des données JSON. Mais je savais aussi qu'il existe un deuxième type - AnyObject . Et récemment, j'ai pensé à la différence entre ces deux types.

Selon la documentation Apple:

  • Tout - peut représenter une instance de tout type
  • AnyObject - peut représenter une instance de n'importe quelle classe

Pour le dire un peu plus facilement, alors:

  • Any est utilisé pour tous les types.
  • AnyObject - utilisé pour les types de classe

Vérifions en pratique ces deux types. Commençons par le type Any .

Pour ce faire, créez un tableau de type Any et imprimez-le.

let anyArray: [Any] = ["Macbook", 1, 2] print(anyArray) Console: ["Macbook", 1, 2] 

Comme nous pouvons le voir, Any vous permet de travailler avec différents types de données en même temps (String, Int).
Selon la documentation, les éléments ( String et Int ) de ce tableau sont des structures qui sont des types de valeur, donc théoriquement AnyObject ne devrait pas fonctionner.

Pour vérifier cela, créez un tableau identique de type AnyObject .

 let anyObjectArray: [AnyObject] = ["Macbook", 1, 2] 

Comme prévu, le compilateur nous donne une erreur sur l'impossibilité de convertir le type "String / Int" en type AnyObject

Erreur du compilateur
Impossible de convertir la valeur de type "Int" en type d'élément attendu "AnyObject"
Impossible de convertir la valeur de type "Int" en type d'élément attendu "AnyObject"
Impossible de convertir la valeur de type "String" en type d'élément attendu "AnyObject"

Mais essayons d'apporter nos trois types à AnyObject et d'imprimer le résultat.

 let anyObjectArray: [AnyObject] = ["Macbook" as AnyObject, 1 as AnyObject, 2 as AnyObject] print(anyObjectArray) Console: [Macbook, 1, 2] 

L'erreur du compilateur a disparu. Comme nous pouvons le voir, une chaîne Macbook ressemble clairement à une chaîne, mais n'a pas les guillemets habituels comme le type String dans Swift.

Essayons d'imprimer le tableau à l'aide d'une boucle pour vérifier leur type réel.

 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 

Une chaîne est de type String. Comme dit précédemment, les chaînes dans Swift sont des structures, pas des types de classes. Par conséquent, nous ne devrions pas pouvoir les utiliser comme AnyObject.

Faisons quelques expériences supplémentaires avec notre réseau. Essayons de vérifier les types d'Objective - C: NSString et 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 

Alors pourquoi cela se produit-il?


Dans le cadre de sa compatibilité avec Objective-C, Swift propose des moyens pratiques et efficaces de travailler avec les plateformes Cocoa.

Swift convertira automatiquement certains types Objective-C en types Swift et certains types Swift en types Objective-C. Les types qui peuvent être convertis entre Objective-C et Swift sont appelés concaténés .

En d'autres termes, le compilateur fait tout son possible pour être flexible dans la gestion de ces types en convertissant et en créant automatiquement des "ponts", tout en évitant les plantages d'applications.

Quand utiliser AnyObject?


Comme indiqué dans la documentation Apple, AnyObject peut être utilisé pour travailler avec des objets dérivés de Class mais n'ayant pas de classe racine commune.

Dans Swift 3, le type d'ID dans Objective - C est désormais mappé au type Any dans Swift, qui décrit la valeur de tout type, qu'il s'agisse d'une classe, d'une énumération, d'une structure ou de tout autre type Swift. Cette modification rend les API Objective - C plus flexibles dans Swift, car les types de valeur définis par Swift peuvent être transmis aux API Objective - C et récupérés en tant que types Swift, éliminant ainsi le besoin de types de «bloc» manuels.

Ainsi, il est conseillé d'utiliser AnyObject lorsque vous souhaitez restreindre le protocole afin qu'il ne puisse être utilisé qu'avec des classes, et Any dans les autres cas .

Apple ajoute :
N'utilisez Any et AnyObject que lorsque vous avez explicitement besoin du comportement et des capacités qu'ils fournissent. Il est toujours préférable d'être précis sur les types que vous prévoyez d'utiliser dans votre code.

Source: https://habr.com/ru/post/fr483494/


All Articles