【Swift】コードをコンパクトに記述できるオプショナルチェーン(optional chaining)の性質と活用例

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

20150108-113233.jpg

最近はSwiftでコーディングすることが多い@akio0911です。今日はSwiftでコードをコンパクトに記述できる「オプショナルチェーン」という仕組みについて紹介します!

    

スポンサード リンク

オプショナルチェーンの基本

オプショナル型なプロパティを持つ、以下の様なクラス群が定義されていたとします。

class A {
    var b:B?
}

class B {
    var c:C?
}

class C {
    var name:String = ""
    var age:Int = 0

    func isMale() -> Bool {
        return true
    }
    
    func display() {
        print("name = \(name), age = \(age)")
    }
}

    

そして、以下のようにオブジェクトを生成したとします。

var objectC = C()
objectC.name = "sato"
objectC.age = 35

var objectB = B()
objectB.c = objectC

var objectA:A? = A()
objectA!.b = objectB

    

ここでobjectCのnameプロパティにアクセスしたいとします。こんな時に活用できるのが「オプショナルチェーン (optional chaining, optional chain) 」です。

let n = objectA?.b?.c?.name

    

上記のコードは以下の様な動きをします。

  • objectA, b, c の全てがnilでは無い場合、定数nにはnameが代入される
  • objectA, b, c のいずれかがnilの場合、定数nはnilとなる

この時、定数nはnilになりえるので、その型はnameと同じString型ではなく、String?型(オプショナル)となります。

    

オプショナル束縛と組み合わせる

オプショナルチェーンは、以下のようにオプショナル束縛 (optional binding) と組み合わせて使うことができます。

if let name = objectA?.b?.c?.name {
    // objectA, b, c の全てがnilでは無い場合、ここが実行される
    println(name)
}

    

辞書へのアクセスにオプショナルチェーンを使ってみる

SwiftのDictionaryは、キーを指定してアクセスする際にオプショナル型が返ってくるので、以下のように記述することができます。

var dictionary = [String:C]()
dictionary["sato"] = objectC

if let name = dictionary["sato"]?.name {
    // dictionary["sato"] が存在する場合、ここが実行される
    println(name)
}

    

オプショナルチェーンでメソッドを呼び出す

オプショナルチェーンではメソッドも呼び出すことができますが、その場合はメソッドの返り値のオプショナル型が返ってきます。

例えば先程のCクラスで定義されているisMaleメソッドは返り値はBoolなので、このメソッドをオプショナルチェーン内で呼び出すとBool?となります。

// objectA, b, c の全てがnilではない時のみ、isMale()メソッドが呼び出される。
// isMale()の返り値はBool型なので、変数maleの型はBool?(オプショナル)となる。
let male = objectA?.b?.c?.isMale()

    

オプショナルチェーンでメソッドが呼び出されたかどうかをチェックする

オプショナル束縛 (optional binding) と組み合わせることで、isMale()メソッドが呼び出されたか否かによって処理を分岐させることができます。

if let male = objectA?.b?.c?.isMale() {
    println("isMale()が呼び出された")
}else{
    println("isMale()が呼び出されなかった")
}

    

オプショナルチェーンで返り値のないメソッドが呼び出されたかどうかをチェックする

Swiftでは返り値がないメソッドも実際には空タプル () を返すので、返り値がないメソッドをオプショナルチェーン内で呼び出した場合は空タプルのオプショナル ()? を返します。

// retの型は空タプルのオプショナル ()?
let ret = objectA?.b?.c?.display()

    

よって、このことを利用して、返り値がないメソッドが呼び出されたか否かをチェックすることができます。

if objectA?.b?.c?.display() != nil {
    println("display() が呼び出された")
}else{
    println("display() が呼び出されていない")
}

    

オプショナルチェーンを代入先として使う

オプショナルチェーンは、値の参照やメソッドの呼び出しだけでなく、代入先としても使用することができます。

// objectA, b, c の全てがnilでは無いときのみ、代入が実行される
objectA?.b?.c?.name = "suzuki"

    

また、この代入操作は空タプルのオプショナルを返します。よって以下のようにして代入が成功したか否かをチェックすることができます。

if (objectA?.b?.c?.name = "suzuki") != nil {
    println("代入できた")
}else{
    println("代入できなかった")
}

    

@akio0911はこう思った。

オプショナル束縛だけを使っているとコードが煩雑になりがちですが、今回紹介したオプショナルチェーンを使うことでかなりコードをコンパクトに記述できると思います。

    

ちなみにオプショナルチェーンについては以下の書籍が詳しかったです!

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

follow us in feedly

Feedlyで最新記事を購読

Twitterで更新情報をゲット!

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

関連記事

I20160209-123839.jpg

【Swift】プロパティのsetとgetには異なるアクセス修飾子を指定できる

Swiftでは、プロパティのセッタ(set節)とゲッタ(get節)に異なるアクセス修飾子

記事を読む

20140721-170305.jpg

プロトタイピングのツールや手法を学べる「プロトタイピング実践ガイド」

株式会社インプレスさまより献本御礼。 プロトタイピング実践ガイド スマホアプリの効率的なデザイ

記事を読む

Auto LayoutやStoryboardの仕組みをしっかり理解できる!「UIKit徹底解説」

インプレスジャパン様より献本御礼。UIKit周りを中心に、「Auto Layout」「Story

記事を読む

I20160128-101452.jpg

【解決】Playground execution terminated because the process stopped unexpectedlyが出た時の対処法

Xcodeのプレイグラウンドで「Playground execution terminated

記事を読む

I20160228-162014.jpg

詳解 Swift 改訂版のKindle版が発売。リフローに対応!

今日気付いたんですが、「詳解 Swift 改訂版」のKindle版がいつの間にか発売されていまし

記事を読む

I20151031-175009.jpg

初心者にオススメの本!Swiftではじめる iPhoneアプリ開発の教科書【Swift 2&Xcode 7対応】

     Xcode 7とSwift 2に対応したアプリ開発の入門書籍「Swiftでは

記事を読む

20141031-150402.jpg

アップルのベータテストサービス「TestFlight」が正式公開

アップルが先週の木曜、ベータテストサービス「TestFlight」を正式に公開しました。 Te

記事を読む

I20160217-170931.jpg

2016年2月15日以降、Missing iOS Distribution Signing identity for XXX というエラーが出た場合の解決方法

2016年2月15日以降、AppStoreへの申請やipaファイルのエクスポートで「Missin

記事を読む

20140818-141439.jpg

iPhoneアプリを作りたい開発初心者にまずはやってみて欲しい3つのこと

今日は、これからiPhoneアプリを作りたい開発初心者の方にやってもらいたいことを書いてみた

記事を読む

20160509-200435

【Auto Layout】readableContentGuideを使わずに最大幅を定義する

iOS 9からUIViewにreadableContentGuideが追加されましたが、re

記事を読む

【Mac】macOSのメール(Mail.app)でGmailをサクサク快適に使う方法

macOSに搭載されているメールアプリ、いわゆるMail.ap

【メンズネイル】新宿区大久保のネイルサロンで紫とピンクのネイルにしてもらった

2016年11月12日、東京都新宿区大久保にあるネイルサロン「

[Xcode][Swift]ボタンなどの同時タップを禁止する

iOSで、ボタンなどの同時タップを禁止する方法を紹介します。

【HomeKit】家の照明をSiriで制御できるようにしてみた

Apple製品と家電を連携するシステム「HomeKit(ホーム

【メンズネイル】新宿区大久保のサロンでターコイズとピンクのメタルネイルにしてもらった

2016年10月22日、いつもお世話になっているネイルサロン「

→もっと見る

PAGE TOP ↑