誰かが理由を説明できますか@objc
キーワードは、コードをコンパイルするためにここで必要ですか?
私が理解したように、このキーワードは、ObjCメッセージメソッドのディスパッチを機能させるために使用されます。ただし、これはNSObject
インスタンスではありません。
class MyClass {
}
extension MyClass {
@objc func extensionMethod() { /// THIS LINE
print("A")
}
}
class SubClass: MyClass {
override func extensionMethod() {
print("B")
}
}
@objc
キーワードはメッセージディスパッチとdynamic
を有効にしますか?か否か?
@objc
キーワードはdynamic
と同様にメッセージディスパッチを有効にしますか?
通常ではありません。通常、@objc
属性は、それ自体で特定のクラスメンバーをObjective-Cに公開するだけです。Swiftは、テーブルまたは静的ディスパッチを使用して、自由にディスパッチできます。 Swiftが呼び出すときにメッセージディスパッチを使用する場合は、メンバーをdynamic
としてマークする必要があります。
ただし、非最終的な@objc
クラスextensionメンバーの場合、Swiftは自動的にdynamic
であると推測します。どうして?相互運用性の理由から、Swiftでは、@objc
拡張メンバーをオーバーライドおよびオーバーライドできます(サブクラスカテゴリのObj-Cメソッドをオーバーライドする方法と同様)。この動作を実現するために、SwiftはObj-Cメッセージディスパッチに依存しています。
したがって、拡張機能では、@objc
はdynamic
を推測します。拡張メンバーは現在Swiftクラスのvtableに追加できないため(Swift vtableには現在メンバーを動的に追加できないため)、Obj-Cランタイムに公開せずに拡張メンバーをオーバーライドすることはできません。実行時)。
しかし、これは
NSObject
インスタンスではありません。
Appleプラットフォーム(つまり、Obj-C相互運用機能を備えたプラットフォーム)では、all SwiftクラスはObj-Cランタイムに公開され、すべて暗黙的にNSObjectProtocol
に準拠する_SwiftObject
と呼ばれる特別なObj-C基本クラス。したがって、Swiftクラスは、NSObject
から継承しなくても、メッセージディスパッチを利用できます。