Any und AnyObject in Swift. Was ist ihr Unterschied?

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 konvertieren

Compilerfehler
Wert 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.

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


All Articles