Ich bin neu in der Mac / iPhone-Programmierung und in Objective-C. In C # und Java gibt es "Generics", Sammlungsklassen, deren Mitglieder nur vom deklarierten Typ sein können. Zum Beispiel in C #
Dictionary<int, MyCustomObject>
kann nur Schlüssel enthalten, die Ganzzahlen sind, und Werte vom Typ MyCustomObject. Gibt es einen ähnlichen Mechanismus in Objective-C?
Antworten:
In Xcode 7 hat Apple "Lightweight Generics" in Objective-C eingeführt. In Objective-C generieren sie Compiler-Warnungen, wenn eine Typinkongruenz vorliegt.
Und im Swift-Code erzeugen sie einen Compilerfehler:
Lightweight Generics sind für die Verwendung mit NSArray, NSDictionary und NSSet vorgesehen. Sie können sie jedoch auch Ihren eigenen Klassen hinzufügen:
Objective-C verhält sich wie zuvor mit Compiler-Warnungen.
Swift ignoriert die allgemeinen Informationen jedoch vollständig. (Nicht mehr wahr in Swift 3+.)
Interaktion mit Objective-C-APIs
quelle
MyClass <Foo: id<Bar>>
, wird Ihr Swift Code Werte annehmen , die Art Ihrer Einschränkung sind, die man gibt etwas zu arbeiten. Bei spezialisierten Unterklassen vonMyClass
würden jedoch ihre spezialisierten Typen ignoriert (effektiv als das gleiche wie ein generisches angesehenMyClass
). Siehe github.com/bgerstle/LightweightGenericsExampleNein, in Objective-C gibt es keine Generika, es sei denn, Sie möchten C ++ - Vorlagen in Ihren eigenen benutzerdefinierten Sammlungsklassen verwenden (von denen ich dringend abraten möchte).
Objective-C verfügt über eine dynamische Typisierung als Funktion. Dies bedeutet, dass sich die Laufzeit nicht um den Typ eines Objekts kümmert, da alle Objekte Nachrichten empfangen können. Wenn Sie einer integrierten Sammlung ein Objekt hinzufügen, werden diese nur so behandelt, als wären sie vom Typ
id
. Aber keine Sorge, senden Sie einfach wie gewohnt Nachrichten an diese Objekte. es wird gut funktionieren (es sei denn natürlich, eines oder mehrere der Objekte in der Sammlung antworten nicht auf die Nachricht, die Sie senden) .Generika werden in Sprachen wie Java und C # benötigt, da es sich um starke, statisch typisierte Sprachen handelt. Völlig anderes Ballspiel als die dynamische Tippfunktion von Objective-C.
quelle
Nein, aber um es klarer zu machen, können Sie es mit dem Objekttyp kommentieren, den Sie speichern möchten. Ich habe dies einige Male gesehen, wenn Sie heutzutage etwas in Java 1.4 schreiben müssen.
oder
quelle
In Objective-C gibt es keine Generika.
Aus den Dokumenten
quelle
Apple hat ObjC in XCode 7 Generika hinzugefügt:
Siehe hier: https://developer.apple.com/library/prerelease/mac/documentation/Swift/Conceptual/BuildingCocoaApps/WorkingWithCocoaDataTypes.html#//apple_ref/doc/uid/TP40014216-CH6-ID61
quelle
Dies wurde in Xcode 7 veröffentlicht (endlich!)
Beachten Sie, dass es sich bei Objective C-Code nur um eine Überprüfung zur Kompilierungszeit handelt. Es tritt kein Laufzeitfehler auf, wenn nur der falsche Typ in eine Sammlung eingefügt oder einer typisierten Eigenschaft zugewiesen wird.
Erklären:
Verwenden:
Sei vorsichtig mit diesen
*
s.quelle
Generische NSArrays können durch Unterklassen
NSArray
und Neudefinition aller bereitgestellten Methoden mit restriktiveren Methoden realisiert werden. Beispielsweise,müsste neu definiert werden in
wie
für ein NSArray, das nur NSStrings enthält.
Die erstellte Unterklasse kann als Drop-In-Ersatz verwendet werden und bietet viele nützliche Funktionen: Compiler-Warnungen, Eigenschaftszugriff, bessere Codeerstellung und -vervollständigung in Xcode. All dies sind Funktionen zur Kompilierungszeit. Die eigentliche Implementierung muss nicht neu definiert werden. Die Methoden von NSArray können weiterhin verwendet werden.
Es ist möglich, dies zu automatisieren und auf nur zwei Anweisungen zu reduzieren, wodurch es Sprachen nahe kommt, die Generika unterstützen. Ich habe mit WMGenericCollection eine Automatisierung erstellt , bei der Vorlagen als C-Präprozessor-Makros bereitgestellt werden.
Nach dem Importieren der Header-Datei, die das Makro enthält, können Sie ein generisches NSArray mit zwei Anweisungen erstellen: eine für die Schnittstelle und eine für die Implementierung. Sie müssen nur den Datentyp, den Sie speichern möchten, und die Namen für Ihre Unterklassen angeben. WMGenericCollection stellt solche Vorlagen für
NSArray
,NSDictionary
undNSSet
, sowie deren wandelbar Pendants.Ein Beispiel:
List<int>
könnte durch eine benutzerdefinierte Klasse namens aufgerufen werdenNumberArray
, die mit der folgenden Anweisung erstellt wird:Sobald Sie erstellt haben
NumberArray
, können Sie es überall in Ihrem Projekt verwenden. Es fehlt die Syntax von<int>
, aber Sie können Ihr eigenes Namensschema auswählen, um diese als Klassen als Vorlagen zu kennzeichnen.quelle
Schauen Sie sich an:
https://github.com/tomersh/Objective-C-Generics
Es scheint eine Art Generikum für arme Männer zu sein, indem der Protokollprüfungsmechanismus neu verwendet wird.
quelle
Jetzt werden Träume wahr - es gibt Generika in Objective-C seit heute (danke, WWDC). Es ist kein Witz - auf der offiziellen Seite von Swift:
Und ein Bild, das dies beweist:
quelle
Ich will nur hier rein springen. Ich habe hier einen Blog-Beitrag über Generika geschrieben.
Ich möchte dazu beitragen, dass Generika zu jeder Klasse hinzugefügt werden können , nicht nur zu den Sammlungsklassen, wie Apple angibt.
Ich habe dann erfolgreich zu einer Vielzahl von Klassen hinzugefügt, da diese genauso funktionieren wie Apples Sammlungen. dh. Überprüfung der Kompilierungszeit, Vervollständigung des Codes, Ermöglichen des Entfernens von Abgüssen usw.
Genießen.
quelle
Die von Apple- und GNUStep-Frameworks bereitgestellten Collections-Klassen sind insofern semi-generisch, als sie davon ausgehen, dass sie Objekte erhalten, von denen einige sortierbar sind und andere auf bestimmte Nachrichten reagieren. Für Grundelemente wie Floats, Ints usw. ist die gesamte C-Array-Struktur intakt und kann verwendet werden. Für sie gibt es spezielle Wrapper-Objekte zur Verwendung in den allgemeinen Auflistungsklassen (z. B. NSNumber). Darüber hinaus kann eine Collection-Klasse in Unterklassen unterteilt (oder speziell über Kategorien geändert) werden, um Objekte eines beliebigen Typs zu akzeptieren. Sie müssen jedoch den gesamten Code für die Typverarbeitung selbst schreiben. Nachrichten können an jedes Objekt gesendet werden, sollten jedoch null zurückgeben, wenn dies für das Objekt ungeeignet ist, oder die Nachricht sollte an ein geeignetes Objekt weitergeleitet werden. Echte Typfehler sollten zur Kompilierungszeit und nicht zur Laufzeit abgefangen werden. Zur Laufzeit sollten sie behandelt oder ignoriert werden. Schließlich bietet Objc Funktionen zur Laufzeitreflexion, um schwierige Fälle zu behandeln, und die Nachrichtenantwort, der bestimmte Typ und die Dienste können für ein Objekt überprüft werden, bevor eine Nachricht gesendet oder in eine unangemessene Sammlung gestellt wird. Beachten Sie, dass unterschiedliche Bibliotheken und Frameworks unterschiedliche Konventionen hinsichtlich des Verhaltens ihrer Objekte beim Senden von Nachrichten anwenden, für die sie keine Code-Antworten haben, daher RTFM. Abgesehen von Spielzeugprogrammen und Debugging-Builds sollten die meisten Programme nicht abstürzen müssen, es sei denn, sie vermasseln es wirklich und versuchen, fehlerhafte Daten in den Speicher oder auf die Festplatte zu schreiben, illegale Operationen auszuführen (z. B. durch Null teilen, aber Sie können das auch abfangen) oder darauf zuzugreifen sperrt Systemressourcen. Die Dynamik und Laufzeit von Objective-C ermöglicht es, dass Dinge ordnungsgemäß fehlschlagen und in Ihren Code integriert werden sollten. (TIPP) Wenn Sie Probleme mit der Großzügigkeit Ihrer Funktionen haben, versuchen Sie etwas Spezifität. Schreiben Sie die Funktionen mit bestimmten Typen auf und lassen Sie die Laufzeit zur Laufzeit die entsprechende Elementfunktion auswählen (deshalb werden sie Selektoren genannt!).
quelle