t__nabe_log

雑多 作業、学習ログ多め。

Swiftのextension内でのmethodのoverrideについて

@_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についての質問

stackoverflow.com

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にお願いします。