[解決済み] Swiftのプロトコルでオプションのメソッドを定義するには?
質問
Swiftで可能ですか?もし不可能なら、それを行うための回避策はあるのでしょうか?
どのように解決するのですか?
1. デフォルトの実装を使用する(望ましい)。
protocol MyProtocol {
func doSomething()
}
extension MyProtocol {
func doSomething() {
/* return a default value or just leave empty */
}
}
struct MyStruct: MyProtocol {
/* no compile error */
}
メリット
-
Objective-Cランタイムは含まれません (まあ、少なくとも明示的にはやってない)。つまり、構造体、列挙型、非構成型に適合させることができるのです。
NSObject
クラスはこれに準拠します。また、強力なジェネリックスシステムを利用することができます。 -
<強い すべての要件が満たされていることを常に確認することができます このようなプロトコルに準拠した型に遭遇したとき。それは常に具体的な実装か、デフォルトの実装のどちらかである。これは、他の言語では、インターフェイスやコントラクトがそうである。
デメリット
-
非対応
Void
の要件がある場合は、妥当なデフォルト値 これは常に可能とは限りません。しかし、この問題に遭遇した場合、その要件は本当はデフォルトの実装を持つべきではないか、あるいはAPI設計時にミスを犯したことを意味します。 -
デフォルトの実装と全くない実装の区別がつかない 少なくとも、特別な戻り値でその問題に対処しない限りは。次のような例を考えてみましょう。
protocol SomeParserDelegate { func validate(value: Any) -> Bool }
を返すだけのデフォルトの実装を用意した場合
true
- というのは、一見すると問題ないように思えます。では、次のような疑似コードを考えてみましょう。final class SomeParser { func parse(data: Data) -> [Any] { if /* delegate.validate(value:) is not implemented */ { /* parse very fast without validating */ } else { /* parse and validate every value */ } } }
このような最適化を実装する方法はありません。デリゲートがメソッドを実装しているかどうかを知ることはできないのです。
この問題を解決する方法はいろいろありますが(オプショナルクロージャの使用、操作ごとに異なるデリゲートオブジェクトなど)、この例では問題が明確に示されていますね。
2. 使用方法
@objc optional
.
@objc protocol MyProtocol {
@objc optional func doSomething()
}
class MyClass: NSObject, MyProtocol {
/* no compile error */
}
メリット
- デフォルトの実装は必要ありません。 オプションのメソッドや変数を宣言するだけで、すぐに使えるようになります。
デメリット
-
プロトコルの能力を著しく制限する は、すべての適合する型がObjective-Cと互換性があることを要求しています。つまり
NSObject
は、このプロトコルに準拠することができます。構造体、列挙型、関連型は不可。 -
オプションのメソッドが実装されているかどうかを常に確認する必要があります。 をオプションで呼び出すか、適合する型がそれを実装しているかどうかをチェックすることで、実装されています。これは、オプショナルメソッドを頻繁に呼び出す場合、多くの定型句を導入することになるかもしれません。
関連
-
[解決済み] 使用しているSwiftのバージョンを確認するにはどうすればよいですか?
-
[解決済み] SwiftからObjective-Cのコードを呼び出すにはどうしたらいいですか?
-
[解決済み] Swiftで#pragmaマーク?
-
[解決済み] Swift Betaのパフォーマンス:配列のソート
-
[解決済み] Javaオプションパラメータ
-
[解決済み] Xcode 7のエラーです。"Missing iOS Distribution signing identity for ..." (iOS配布用署名IDがありません)
-
[解決済み] SwiftでIntをStringに変換する
-
[解決済み] 純粋な」Swift で弱いプロトコル参照を作るには (@objc なしで) どうしたらいいですか?
-
[解決済み] SwiftでUIAlertViewを作成するにはどうしたらいいですか?
-
[解決済み] Swift で HTTP リクエストを行うにはどうしたらいいですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
JenkinsがIOSを自動パッケージングしてモミを配布
-
[解決済み] カスタムオブジェクトを含むNSMutableArrayをソートするにはどうすればよいですか?
-
[解決済み] iOSのバージョンを確認する方法を教えてください。
-
[解決済み] Objective-Cで文字列が空かどうかをテストするにはどうすればよいですか?
-
[解決済み] UINavigationBarの1px下の行を非表示にする方法
-
[解決済み] Swiftを使用してアプリのバージョンとビルド番号を取得するにはどうすればよいですか?
-
[解決済み] UIImageのサイズを変更する最も簡単な方法?
-
[解決済み] 16進カラーバリューの使用方法
-
[解決済み] UITextBorderStyleNoneを使用してUITextFieldのパディングを設定する
-
[解決済み] セキュリティで保護されたWebサービスにもアクセスするiOSアプリで、Facebook認証を行うためのデザイン