Ich habe einige Isa getestet, die mit Swift sprudeln , und festgestellt, dass es nur funktioniert, wenn NSObject eine Superklasse ist (direkt oder weiter oben) oder indem ich die '@objc'-Dekoration verwende. Andernfalls folgt es einem statischen und vtable-Versandstil wie C ++.
Ist es normal, eine Swift-Klasse ohne eine Cocoa / NSObject-Basisklasse zu definieren? Wenn es mich betrifft, bedeutet dies, auf einen Großteil der Dynamik von Objective-C zu verzichten, wie z. B. das Abfangen von Methoden und die Introspektion zur Laufzeit.
Das dynamische Laufzeitverhalten steht im Mittelpunkt von Funktionen wie Eigenschaftsbeobachtern, Kerndaten, aspektorientierter Programmierung , Messaging höherer Ordnung , Analyse- und Protokollierungsframeworks usw.
Durch die Verwendung des Methodenaufrufstils von Objective-C werden einem Methodenaufruf etwa 20 Maschinencode-Operanden hinzugefügt , sodass in bestimmten Situationen ( viele enge Aufrufe von Methoden mit kleinen Körpern ) der statische und vtable-Versand im C ++ - Stil eine bessere Leistung erzielen kann.
Ist es angesichts der allgemeinen 95-5-Regel ( 95% der Leistungssteigerungen stammen aus der Optimierung von 5% des Codes ) nicht sinnvoll, mit den leistungsstarken dynamischen Funktionen zu beginnen und bei Bedarf zu härten?
quelle
Antworten:
Schnelle Klassen, die Unterklassen von NSObject sind:
objc_msgSend()
für Aufrufe (der meisten) ihrer MethodenSchnelle Klassen, die keine Unterklassen von NSObject sind:
objc_msgSend()
für Aufrufe ihrer Methoden verwenden (standardmäßig)Durch die Unterklasse von NSObject in Swift erhalten Sie Flexibilität bei der Objective-C-Laufzeit, aber auch bei der Objective-C-Leistung. Das Vermeiden von NSObject kann die Leistung verbessern, wenn Sie die Flexibilität von Objective-C nicht benötigen.
Bearbeiten:
Bei Xcode 6 Beta 6 wird das dynamische Attribut angezeigt. Auf diese Weise können wir Swift anweisen, dass eine Methode den dynamischen Versand verwenden soll, und daher das Abfangen unterstützen.
quelle
Ich fand auch heraus, dass ich, wenn ich eine Swift-Klasse auf NSObject basierte, ein unerwartetes Laufzeitverhalten sah, das Codierungsfehler verbergen konnte. Hier ist ein Beispiel.
In diesem Beispiel, in dem wir nicht auf NSObject basieren, erkennt der Compiler den Fehler in testIncorrect_CompilerShouldSpot korrekt und meldet "... 'MyClass' kann nicht in 'MirrorDisposition' konvertiert werden."
In diesem Beispiel , wo wir auf der Basis NSObject , der Compiler nicht den Fehler in testIncorrect_CompilerShouldSpot vor Ort:
Ich denke, die Moral ist, nur auf NSObject zu basieren, wo man wirklich muss!
quelle
Gemäß der Sprachreferenz müssen Klassen keine Standardstammklasse unterklassifizieren, sodass Sie eine Superklasse nach Bedarf einschließen oder weglassen können.
Beachten Sie, dass das Weglassen einer Oberklasse in der Klassendeklaration keinerlei implizite Basis-Oberklasse zuweist. Es definiert eine Basisklasse, die effektiv zur Wurzel für eine unabhängige Klassenhierarchie wird.
Aus der Sprachreferenz:
Der Versuch,
super
von einer Klasse ohne Superklasse (dh einer Basisklasse) zu referenzieren, führt zu einem Fehler bei der Kompilierungquelle
Ich glaube, dass die überwiegende Mehrheit der Swift-Daten dies nicht sein wird
objc
. Nur diejenigen Teile, die mit der Objective C-Infrastruktur kommunizieren müssen, werden explizit als solche gekennzeichnet.Inwieweit der Sprache eine Introspektion zur Laufzeit hinzugefügt wird, weiß ich nicht. Das Abfangen von Methoden wird wahrscheinlich nur möglich, wenn die Methode dies ausdrücklich zulässt. Dies ist meine Vermutung, aber nur die Sprachdesigner bei Apple wissen wirklich, wohin sie wirklich gehen.
quelle
educated guesses
in ein paar Jahren schaffen. Aber im Moment ist es nur ein großes Fragezeichen.Folgendes wurde aus Apples Swift-eBook kopiert und gibt eine angemessene Antwort auf Ihre Frage:
Basisklasse definieren
Jede Klasse, die nicht von einer anderen Klasse erbt, wird als Basisklasse bezeichnet.
Swift-Klassen erben nicht von einer universellen Basisklasse. Klassen, die Sie ohne Angabe einer Oberklasse definieren, werden automatisch zu Basisklassen, auf denen Sie aufbauen können.
Referenz
https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Inheritance.html#//apple_ref/doc/uid/TP40014097-CH17-XID_251quelle
Es ist normal. Schauen Sie sich die Designziele von Swift an: Das Ziel ist es, große Klassen von Programmierproblemen verschwinden zu lassen. Methoden-Swizzling ist wahrscheinlich nicht eines der Dinge, die Sie mit Swift tun möchten.
quelle