Swiftのextension内でのmethodのoverrideについて
extensionでoverrideするのよろしくなかったような気がするけど、どうなんだろう( ´・?・`)あるいは実際普通に動いてしまうからあり?( ´・?・`)
— 🐶 mono - iOS/SwiftとFlutterとラブラドールの雑種( ´・‿・`) (@_mono) 2019年1月30日
iOSのステータスバーを自在に扱う https://t.co/nJFmYQYdas #Qiita pic.twitter.com/ZrrYtpWL6v
@_monoさんのツイートがきっかけでdocumentationやstackoverflowを調べたりplaygroundで遊んだりしたのでそのログ。
extensionでoverride出来る時と出来ない時がある
UIViewControllerのSubclassだとmethodのoverrideが出来る。UIViewControllerのSubclassだと出来るのでは?と思ってObjective-Cのクラスを継承していないSuperclassを用意してそれを継承したSubclassでmethodのoverrideを行ってみたら警告が出た。
Overriding non-@objc declarations from extensions is not supported
SuperClassにNSObjectを継承させてobjc由来のmethodを定義して、SubClassにextension内でoverrideさせると警告はなくなる。
// 警告が出ないコード class Animal: NSObject { @objc dynamic func say() -> String { return "Animal" } } class Cat: Animal { } extension Cat { override func say() -> String { return "Cat" } }
objc由来の型に関してはSwiftで書いていても動作はObjective-Cのruntimeのよう。 classとmethodの療法がObjective-Cでないと動かないのはobjc_msgSendでメソッドコールをしている。
ここまでの参考 Swiftにおけるmethod dispatchについて qiita.com
Objective-Cの動的なメソッド呼び出しについて qiita.com
StackoverflowでのOverriding methods in Swift extensionsについての質問
Appleのdocumentationには
Extensions add new functionality to an existing class, structure, enumeration, or protocol type. This includes the ability to extend types for which you do not have access to the original source code (known as retroactive modeling). Extensions are similar to categories in Objective-C. (Unlike Objective-C categories, Swift extensions do not have names.) Extensions can add new functionality to a type, but they cannot override existing functionality.
https://docs.swift.org/swift-book/LanguageGuide/Extensions.html
とあるのでこれらのことを踏まえると今まで通りSwiftでは、基本的にextension内でmethodのoverrideを行わない方針で問題なさそう。 何かご指摘があればにt__nabe(なべ) (@t__nabe) | Twitterにお願いします。