webentwicklung-frage-antwort-db.com.de

Swift 3: NSObject subclassing oder nicht?

Ich habe einige Posts wie this über den Unterschied zwischen der Unterklasse NSObject in Swift oder einfach mit ihrer eigenen Basis class ohne Unterklasse gelesen. Aber es sind alles ein bisschen alte Beiträge, und mir ist dieses Thema nicht klar.

Wann sollte die Unterklasse NSObject sein? Was ist eigentlich der Unterschied zwischen der Unterklasse und nicht der Unterklasse? Was ist aktuell die Empfehlung in Swift?

9
AppsDev

In der Dokumentation von Apple zu NSObject wird zur Einführung Folgendes angegeben:

NSObject ist die Stammklasse der meisten Objective-C-Klassenhierarchien. Über NSObject erben Objekte eine grundlegende Schnittstelle zum Laufzeitsystem und die Fähigkeit, sich als Objective-C-Objekte zu verhalten.

Wie dies nahelegt, müssen Sie need NSObject für in Ihren Code eingeführte Typen in Unterklassen unterteilen, wenn Instanzen dieses Typs sich wie ein Objective-C-Objekt verhalten müssen (oder die Klasse selbst, in einigen selteneren Fällen). .

Mir ist nicht bekannt, dass super explizit Apple eine schriftliche Anleitung gegeben hat, wann nicht NSObject zu unterordnen ist, jenseits von was darauf hindeutet, den dynamischen Versand zu reduzieren oder zu präsentieren Paradigmen für die Wiederverwendung von Code, die nicht auf Unterklassen beruhen, sondern ProtokollErweiterungen , dh die Wiederverwendung von Code ist im Allgemeinen statischer und Werttyp benutzerfreundlich. Ich glaube, es ist fair zu sagen, dass die meisten Swift Programmierer Hinweise von Apple genommen haben, und Swift Sprachfunktionen als Zeichen, um die Einführung von NSObject-basierten Typen zu vermeiden, wenn die Der oben erwähnte Bedarf ist nicht vorhanden. Das heißt, dass Sie in der Regel nur NSObject-basierte Typen einführen, wenn Sie tatsächlich die Objective-C-Dynamik benötigen, am häufigsten, wenn Sie eine Schnittstelle mit Cocoa-APIs benötigen (Besonders häufig, wenn Ihr Code mit der Benutzeroberfläche zusammenhängt: z. B. Ansichtscontroller, Ansichten).

Wie in einer Antwort auf die Frage, auf die Sie verweisen, ausgeführt , mit Objective-C-Dynamik ergibt sich die Leistung der objc_msgSend - basierten Methode dispatch . Obwohl Methoden in Swift - Klassen auch virtuell sind, kann der Compiler schnellere Methoden zum Versenden verwenden, wenn Sie die Methoden nicht explizit mit dem Attribut @objc Markieren - insbesondere wenn Ganze Moduloptimierung ist aktiviert und noch mehr in Swift 3 wobei Klassen nicht standardmäßig für Unterklassen außerhalb des Moduls geöffnet sind, das den Typ definiert .

Abgesehen von der Vermeidung von NSObject können Sie auch klassenbasierte Referenztypen ganz vermeiden in vielen Fällen , wenn Sie Swift schreiben. Schauen Sie sich zum Beispiel die oben verlinkten Videos vom Wertetyp WWDC an oder zum Beispiel dieser Blog-Beitrag als Einführung. Kurz gesagt, vermeiden Sie bei Verwendung von Wertetypen häufig die dynamische Speicherzuweisung und den Mehraufwand für die Referenzzählung (obwohl dies nicht allgemein üblich ist, da Referenztypen als Felder die Einschränkung darstellen).

14
mz2

Ein Grund für die Unterklasse von NSObject ist, dass Sie einige Daten speichern müssen. NSObject und alles, was es beinhaltet (AFAIK), ist der einfachste Weg, um zu NSCoding zu gelangen, das Sie in eine Datei schreiben müssen. 

einige Einsichten finden Sie hier oder hier

1
ArtbyKGH

Ein weiterer Fall, in dem Sie die Unterklasse NSObject eingeben müssen, ist der Fall, wenn Sie möchten, dass Ihre Unterklasse ein Beobachter für KVO ist, d. H.

addObserver(_ observer: NSObject, forKeyPath keyPath: String, options: NSKeyValueObservingOptions = [], context: UnsafeMutableRawPointer?)

erfordert, dass der Beobachter eine NSObject (oder ein Array oder eine Gruppe) ist.

0
strangetimes