Ich neige dazu, nur die Notwendigkeiten (gespeicherte Eigenschaften, Initialisierer) in meine Klassendefinitionen aufzunehmen und alles andere in ihre eigenen zu verschieben extension
, ähnlich einem extension
logischen Block, mit dem ich auch gruppieren würde // MARK:
.
Für eine UIView-Unterklasse würde ich beispielsweise eine Erweiterung für Layout-bezogene Dinge erhalten, eine für das Abonnieren und Behandeln von Ereignissen und so weiter. In diesen Erweiterungen muss ich zwangsläufig einige UIKit-Methoden überschreiben, z layoutSubviews
. Ich habe bis heute keine Probleme mit diesem Ansatz bemerkt.
Nehmen Sie diese Klassenhierarchie zum Beispiel:
public class C: NSObject {
public func method() { print("C") }
}
public class B: C {
}
extension B {
override public func method() { print("B") }
}
public class A: B {
}
extension A {
override public func method() { print("A") }
}
(A() as A).method()
(A() as B).method()
(A() as C).method()
Die Ausgabe ist A B C
. Das macht für mich wenig Sinn. Ich habe gelesen, dass Protokollerweiterungen statisch versendet werden, aber dies ist kein Protokoll. Dies ist eine reguläre Klasse, und ich erwarte, dass Methodenaufrufe zur Laufzeit dynamisch ausgelöst werden. Klar sollte der Anruf C
zumindest dynamisch versendet und produziert werden C
?
Wenn ich die Vererbung entferne NSObject
und C
eine Root-Klasse erstelle, beschwert sich der Compiler und sagt declarations in extensions cannot override yet
, worüber ich bereits gelesen habe. Aber wie NSObject
verändert es die Dinge , eine Wurzelklasse zu haben?
Beide Überschreibungen in ihre Klassendeklaration Verschieben erzeugt A A A
wie erwartet, bewegt nur B
‚produziert s A B B
, bewegt nur A
‘ s produziert C B C
von denen die letzte, macht absolut keinen Sinn für mich: nicht einmal derjenige statisch typisierte A
die erzeugt A
-Ausgang mehr!
Das Hinzufügen des dynamic
Schlüsselworts zur Definition oder eine Überschreibung scheint mir das gewünschte Verhalten "von diesem Punkt in der Klassenhierarchie abwärts" zu geben ...
Lassen Sie uns unser Beispiel in etwas weniger Konstruiertes ändern, was mich tatsächlich dazu gebracht hat, diese Frage zu stellen:
public class B: UIView {
}
extension B {
override public func layoutSubviews() { print("B") }
}
public class A: B {
}
extension A {
override public func layoutSubviews() { print("A") }
}
(A() as A).layoutSubviews()
(A() as B).layoutSubviews()
(A() as UIView).layoutSubviews()
Wir bekommen jetzt A B A
. Hier kann ich die layoutSubviews von UIView keinesfalls dynamisieren.
Wenn Sie beide Überschreibungen in ihre Klassendeklaration verschieben, erhalten Sie A A A
erneut, nur A oder nur B erhalten uns noch A B A
. dynamic
löst wieder meine Probleme.
Theoretisch könnte ich dynamic
alles hinzufügen , was override
ich jemals getan habe, aber ich habe das Gefühl, dass ich hier etwas anderes falsch mache.
Ist es wirklich falsch, extension
s zum Gruppieren von Code zu verwenden, wie ich es tue?