Sehr lange in meinen Projekten, als ich mit dem Typ
Any schrieb , zum Beispiel bei der Verarbeitung von JSON-Daten. Aber ich wusste auch, dass es einen zweiten Typ gibt -
AnyObject . Und kürzlich habe ich über den Unterschied zwischen diesen beiden Typen nachgedacht.
Laut Apple-Dokumentation:
- Any - kann eine Instanz eines beliebigen Typs darstellen
- AnyObject - kann eine Instanz einer beliebigen Klasse darstellen
Einfacher ausgedrückt:
- Any wird für alle Typen verwendet.
- AnyObject - Wird für Klassentypen verwendet
Lassen Sie uns diese beiden Typen in der Praxis überprüfen. Beginnen wir mit dem Typ
Any .
Dazu erstellen Sie ein Array vom Typ Any und drucken es aus.
let anyArray: [Any] = ["Macbook", 1, 2] print(anyArray) Console: ["Macbook", 1, 2]
Wie wir sehen können, können Sie mit Any gleichzeitig mit verschiedenen Datentypen arbeiten (String, Int).
Gemäß der Dokumentation sind die Elemente (
String und
Int ) in diesem Array Strukturen, die
Werttypen sind.
Daher sollte
AnyObject theoretisch nicht funktionieren.
Um dies zu überprüfen, erstellen Sie ein identisches Array vom Typ
AnyObject .
let anyObjectArray: [AnyObject] = ["Macbook", 1, 2]
Wie erwartet gibt uns der Compiler einen Fehler bezüglich der Unmöglichkeit, den Typ "String / Int" in den Typ
AnyObject zu konvertierenCompilerfehlerWert vom Typ "Int" kann nicht in den erwarteten Elementtyp "AnyObject" konvertiert werden
Wert vom Typ "Int" kann nicht in den erwarteten Elementtyp "AnyObject" konvertiert werden
Wert vom Typ "String" kann nicht in den erwarteten Elementtyp "AnyObject" konvertiert werden
Versuchen wir jedoch, unsere drei Typen in AnyObject zu integrieren und das Ergebnis auszudrucken.
let anyObjectArray: [AnyObject] = ["Macbook" as AnyObject, 1 as AnyObject, 2 as AnyObject] print(anyObjectArray) Console: [Macbook, 1, 2]
Der Compilerfehler ist verschwunden. Wie wir sehen können, sieht eine
Macbook- Zeichenfolge eindeutig wie eine Zeichenfolge aus, enthält jedoch nicht die üblichen Anführungszeichen wie die Zeichenfolge in Swift.
Versuchen wir, das Array mit einer Schleife auszudrucken, um den tatsächlichen Typ zu überprüfen.
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
Ein String ist vom Typ String. Wie bereits erwähnt, sind Zeichenfolgen in Swift Strukturen und keine Klassentypen. Daher sollten wir sie nicht als AnyObject verwenden können.
Lassen Sie uns noch ein paar Experimente mit unserem Array durchführen. Lassen Sie uns versuchen, sie auf Typen von Objective - C:
NSString und
NSNumber zu überprüfen .
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
Warum passiert das?
Im Rahmen der Kompatibilität mit Objective-C bietet Swift komfortable und effiziente Möglichkeiten für die Arbeit mit Cocoa-Plattformen.
Swift konvertiert automatisch einige Objective-C-Typen in Swift-Typen und einige Swift-Typen in Objective-C-Typen. Typen, die zwischen Objective - C und Swift konvertiert werden können, werden als
verkettet bezeichnet .
Mit anderen Worten, der Compiler unternimmt alles, um mit diesen Typen flexibel umzugehen, indem er automatisch "Bridges" konvertiert und erstellt und gleichzeitig Anwendungsabstürze verhindert.
Wann sollte AnyObject verwendet werden?
Wie in der Apple-Dokumentation angegeben, kann AnyObject verwendet werden, um mit Objekten zu arbeiten,
die von Class abgeleitet sind
, aber keine gemeinsame Stammklasse haben.
In Swift 3 wird der ID-Typ in Objective-C jetzt dem Any-Typ in Swift zugeordnet, der den Wert eines beliebigen Typs beschreibt, sei es eine Klasse, eine Aufzählung, eine Struktur oder ein anderer Swift-Typ. Diese Änderung macht die Objective-C-APIs in Swift flexibler, da Swift-definierte Werttypen an Objective-C-APIs übergeben und als Swift-Typen abgerufen werden können, sodass keine manuellen Blocktypen erforderlich sind.
Daher
empfiehlt es sich, AnyObject zu verwenden, wenn Sie das Protokoll so einschränken möchten, dass es nur mit Klassen und
in anderen Fällen mit
Any verwendet werden kann .
Apple fügt hinzu :
Verwenden Sie
Any und
AnyObject nur, wenn Sie das von ihnen
bereitgestellte Verhalten und die Funktionen ausdrücklich benötigen. Es ist immer am besten, genau zu sagen, welche Typen in Ihrem Code verwendet werden sollen.