Objective-Cだと今でもマクロを使うことはあります. (ReactiveCocoaなんかも依存していますね.) プロダクトコードで使うのはできたら避けたいマクロですが,ビルド設定によって動作を切り替えたいときとかには結構便利です. しかしながら,Swiftにはマクロは存在しないので,このような手段を使って代替します.
Simple Macros
いわゆる定数を定義するマクロです.
Swiftで定数を定義したいときはlet
を使うべきです.
#define FADE_ANIMATION_DURATION 0.35
このようなマクロによる定数の定義は,
let FADE_ANIMATION_DURATION = 0.35
とlet
を使えば実現できます.
マクロに比べ型チェックがされますので圧倒的にセキュアです.
筆者はこの他に定数を定義するのにcomputed propertyをよく利用します. structureやenum,グローバルコンテキストでも使えて便利なのでオススメです(特にenumで使うのがかっこいいです).
Complex Macros
例えば,MIN
やMAX
のような関数のように働くマクロはSwiftにはエクスポートされません.
このタイプのmacroはCやObjective-Cでは型付けを回避するために使われますが,デバッグやリファクタリングが非常に難しいです.
Swiftではジェネリックタイプもありますので普通に関数で表現してください.
ちなみに,MIN
とMAX
相当の関数はこのように定義されています.
func min<T : Comparable>(x: T, y: T) -> T func max<T : Comparable>(x: T, y: T) -> T
Build Configurations
ビルド時の設定によって動作を変更するときに使います. 以下のものがデフォルトで用意されています.
Function | Valid arguments |
---|---|
os() | OSX, iOS |
arch() | x86_64, arm, arm64, i386 |
例えば,iPhoneシミュレータのみで実行したいコードはこのように書けます.
#if os(iOS) && arch(i386) // do something #endif
よくあるチーム内配布のビルドでのみ実行したいなどの場合は,Other Swift Flags
を使ってください.
Preprocessor Macros
に設定してもSwiftのコードでは参照できないので
TARGETS > Build Settingsから-DBETATESTING
のように指定し,このように使います.
#if BETATESTING // do something #endif
まとめ
従来マクロでやっているようなことをSwiftで実現する代替テクニックを紹介しました.
特にOther Swift Flags
はよくなんだったっけ?となるので覚えておくとよいでしょう.