Swift 2.0で追加されたOptionSetTypeがなかなか便利

公開日: : 最終更新日:2016/02/10 iOSアプリ開発

記事内に広告を含む場合があります。記事内で紹介する商品を購入することで、当サイトに売り上げの一部が還元されることがあります。

20150924-010943.jpg

Swift 2.0で追加されたOptionSetTypeプロトコルがなかなか便利なので紹介したいと思います!

    

Swift 1.2までの記述方法

例えば、SpriteKitのカテゴリビットマスクや衝突テストビットマスクなどを設定する場合、Swift 1.2までは以下のように書くことができました。

let redBallCategory  : UInt32 = 0x1 << 0
let blueBallCategory : UInt32 = 0x1 << 1
let wallCategory     : UInt32 = 0x1 << 2

ballNode.physicsBody?.categoryBitMask = redBallCategory
ballNode.physicsBody?.contactTestBitMask = blueBallCategory | wallCategory

典型的なビットマスクの使い方ですね。

    

あるいは以下のようにstructを使って意味的にまとめて書くこともできました。

struct Category {
    static let RedBall  : UInt32 = 0x1 << 0
    static let BlueBall : UInt32 = 0x1 << 1
    static let Wall     : UInt32 = 0x1 << 2
}

ballNode.physicsBody?.categoryBitMask = Category.RedBall
ballNode.physicsBody?.contactTestBitMask = Category.BlueBall | Category.Wall

    

Swift 2.0のOptionSetTypeを使う

Swift 2.0で追加されたOptionSetTypeを使うと、以下のように記述できます。

struct Category : OptionSetType {
    let rawValue : UInt32

    static let RedBall  = Category(rawValue: 0x1 << 0)
    static let BlueBall = Category(rawValue: 0x1 << 1)
    static let Wall     = Category(rawValue: 0x1 << 2)
}

ballNode.physicsBody?.categoryBitMask = Category.RedBall.rawValue
ballNode.physicsBody?.contactTestBitMask = Category([.BlueBall, .Wall]).rawValue

このケースだと、「structを使うのに比べて、書くのが面倒になってない?」とも思えますが、

    

こんな感じで複数を含むグループを手軽に作れたりします。

struct Category : OptionSetType {
    let rawValue : UInt32
    static let RedBall  = Category(rawValue: 0x1 << 0)
    static let BlueBall = Category(rawValue: 0x1 << 1)
    static let Wall     = Category(rawValue: 0x1 << 2)
        
    static let Balls    = Category([RedBall, BlueBall])
}

ちなみに上記の

Category([RedBall, BlueBall])

は、SetAlgebraTypeプロトコルで用意されている

init< S : SequenceType where S.Generator.Element == Element>(_ sequence: S)

というイニシャライザを使っているみたいです。OptionSetTypeプロトコルはSetAlgebraTypeプロトコルに適合しています。

    

また、2つを合成したグループを動的に作成できたり、

var r1 : Category = Category.Balls.union(Category.Wall)

    

特定の要素を含んでいるかどうかをチェックできるメソッドcontainsが使えたり、

if r1.contains(Category.RedBall) {
    // do something
}

    

特定の要素を追加・削除できるremove/insertのようなメソッドを使えます。

r1.remove(Category.RedBall)
r1.insert(Category.RedBall)

    

詳しくは以下のリファレンスをチェックしてみてください(OptionSetTypeプロトコルは、SetAlgebraTypeプロトコルに適合しています)。

    

@akio0911はこう思った。

SetAlgebraTypeプロトコルのメソッド群が強力なので、うまく使えばコードをスッキリとさせることができそうです。

この記事を書いた人
あきお(@akio0911
派手髪iOSエンジニア。Twitterアカウントは@akio0911。YouTubeチャンネル「あきおチャンネル」にてiOSアプリ開発講座を公開中。著書に「iPhoneアプリ開発レシピ」「cocos2d for iPhoneレッスンノート」など。iOSアプリ開発をテーマとしたオンラインサロン「アプリ道場サロン」を運営。東京・大阪にてアプリ開発講座「アプリクリエイター道場」を主催。

関連記事

この記事が気に入ったら「いいね!」しよう

Twitterで更新情報をゲット!

PAGE TOP ↑