私は必要なもの(保存されたプロパティ、初期化子)だけをクラス定義に入れ、他のものすべてを独自のに移動する傾向があります。これは、グループ化する論理ブロックごとextension
のようなものです。extension
// MARK:
たとえば、UIViewサブクラスの場合、イベントにサブスクライブして処理するためのレイアウトなど、レイアウト関連の拡張機能が必要になります。これらの拡張機能では、必然的にいくつかのUIKitメソッドをオーバーライドする必要がありますlayoutSubviews
。今日まで、このアプローチの問題に気づくことはありませんでした。
このクラス階層を例にとります:
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()
出力はA B C
です。それは私にはほとんど意味がありません。静的にディスパッチされるプロトコル拡張について読みましたが、これはプロトコルではありません。これは通常のクラスであり、実行時にメソッド呼び出しが動的にディスパッチされることを期待しています。明らかに、呼び出しC
は少なくとも動的にディスパッチされ、生成されるべきですC
ですか?
から継承を削除してルートクラスNSObject
を作成C
すると、コンパイラはについて不平を言っdeclarations in extensions cannot override yet
ています。しかしNSObject
、ルートクラスとして持つことはどのように変化しますか?
そのクラス宣言は、生成に両方のオーバーライドの移動A A A
予想通りだけ移動する、B
のが作り出すA B B
、唯一動くA
のが生成しC B C
、私には全く意味がありません最後のうち、:静的に型付けされていなくても1がA
生成A
、それ以上-outputを!
dynamic
キーワードを定義またはオーバーライドに追加すると、「クラス階層のそのポイントから下へ」という望ましい動作が得られるようです...
私たちの例を少し構成の少ないものに変更してみましょう。実際に私はこの質問を投稿させました:
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()
私たちは今、得るA B A
。ここでは、UIViewのlayoutSubviewsを動的にすることはできません。
両方のオーバーライドをクラス宣言に移動するとA A A
再び取得されますが、AまたはBのみが引き続き取得されA B A
ます。dynamic
再び私の問題を解決します。
理論的には、これdynamic
まで行ったすべてoverride
のに追加できますが、ここで何か他のことをしているように感じます。
extension
私のようにコードをグループ化するためにs を使用するのは本当に間違っていますか?