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

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

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

関連記事

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

follow us in feedly

Feedlyで最新記事を購読

Twitterで更新情報をゲット!

LINEでご感想・ご要望お送りください!
(スマホでLINEを起動 > 友だち追加 > QRコード)

PAGE TOP ↑