Swiftにはアサーション系のメソッドとして、次の5つのメソッドがあります。
これらの違いや使い分けについて簡単に紹介します。
Swiftには3つの最適化レベルがある
まず、アサーション系メソッドを説明するために必要な、Swiftの最適化レベルについて簡単に説明します。
コマンドラインでswiftc --help
を実行させてみるとわかる通り、Swiftコンパイラには3つの最適化レベルがあることがわかります。
$ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc --help OVERVIEW: Swift compiler (中略) OPTIONS: -Onone Compile without any optimization -O Compile with optimizations -Ounchecked Compile with optimizations and remove runtime safety checks
上記の説明の通り、-Ounchecked
は-O
よりアグレッシブなオプションというわけです。
まとめると、最適化レベルは次のようになります。
-Onone
は最適化を行いません。Xcodeのデフォルト設定ではDebugビルドにこれが設定されています。-O
は最適化を行います。Xcodeのデフォルト設定ではReleaseビルドにこれが設定されています。-Ounchecked
は最適化を行い、さらに実行時の安全性チェックも消します。Xcodeのデフォルト設定では利用されていません。
アサーション系メソッドまとめ
簡単に言えば、アサーション系メソッドは次の2つの観点で分けられます。
- (最適化レベルによって) 実行されるかどうか
- 条件チェックがあるかどうか
というわけで、各メソッドが各ビルドでチェックが有効になるかどうかをまとめた表がこちら。
表中で○になっている部分は、実行時にチェックが有効になることを意味します。
例えば、assert
はデバッグビルドでは有効になり、実行時にcondition
部分の結果がfalse
ならアサーションエラーとなりますが、
リリースビルドや無チェックビルドでは無効になります (チェックが無効のときはcondition
は常にtrue
になります)。
assert
のcondition
部分がなくて常にfalse
なバージョンが右端assertionFailure
です。
fatalError
には常にfalse
なバージョンはありません。
どう使い分けるか?
各メソッドの機能的な意味よりもメソッド名が持つ意味を重視して、うまく使い分けるのがよさそうです。
fatalError
はXcodeを利用しているとコード補完などでたまにこんな感じで出されることがあります。呼ばれるはずのない未実装のメソッドや来るはずのないcase
なんかで利用するのがよさそうです。
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
GitHub内のSwiftコードを見る限り、やはりメソッド先頭で事前条件に使われていることが多いみたいです (Carthageでもちゃんと使われていますね)。
というわけで、コードの各所でここにはこういう値しか来ないよというのを表明 (assert
) しつつ、関数やループブロックの先頭なんかで事前条件 (precondition
) を書き、想定外のどうしようもないエラーはfatalError
するみたいなのが想定された使いかたかなと思います。
0 件のコメント:
コメントを投稿
注: コメントを投稿できるのは、このブログのメンバーだけです。