Ich neige dazu, nur die Notwendigkeiten (gespeicherte Eigenschaften, Initialisierer) in meine Klassendefinitionen aufzunehmen und alles andere in ihre eigenen zu verschieben extension, ähnlich einem extensionlogischen 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 Czumindest dynamisch versendet und produziert werden C?
Wenn ich die Vererbung entferne NSObjectund Ceine Root-Klasse erstelle, beschwert sich der Compiler und sagt declarations in extensions cannot override yet, worüber ich bereits gelesen habe. Aber wie NSObjectverändert es die Dinge , eine Wurzelklasse zu haben?
Beide Überschreibungen in ihre Klassendeklaration Verschieben erzeugt A A Awie erwartet, bewegt nur B‚produziert s A B B, bewegt nur A‘ s produziert C B Cvon denen die letzte, macht absolut keinen Sinn für mich: nicht einmal derjenige statisch typisierte Adie erzeugt A-Ausgang mehr!
Das Hinzufügen des dynamicSchlü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 Aerneut, nur A oder nur B erhalten uns noch A B A. dynamiclöst wieder meine Probleme.
Theoretisch könnte ich dynamicalles hinzufügen , was overrideich jemals getan habe, aber ich habe das Gefühl, dass ich hier etwas anderes falsch mache.
Ist es wirklich falsch, extensions zum Gruppieren von Code zu verwenden, wie ich es tue?