読者です 読者をやめる 読者になる 読者になる

gl5_progのメモ

自分のためのメモとかまとめとか

Objective-Cで見やすいメソッドチェインの書き方

メソッドチェイン( 名前付きパラメータイディオム )

a().b().c().d()などのようにメソッドの戻り値に連続してメソッド呼び出しを行うことをメソッドチェインと呼ぶそうです。More C++ idiomsでは名前付きパラメータイディオムと呼ばれています。

More C++ Idioms/Named Parameter - Wikibooks, open books for an open world

オブジェクトの生成時にこのイディオムを使うと変数を用意することなく任意のパラメータを任意の順番でセットすることができて便利です。

このメソッドチェインをObjective−Cでやろうとすると読みにくいコードになってしまいます。

// C++の場合
a.b().c().d().e().f();

// Objective-Cの場合
[[[[[a b] c] d] e] f];

もっと複雑な例

// C++の場合
a.b(7).c(x.func()).d(7,x.func()).e(x.func().func()).f();

// Objective-Cの場合
[[[[[a b:7] c:[x func]] d:7 param:[x func]] e:[[x func] func]] f];

C++の場合はまだ読めますが、Objective-Cの場合はもう手におえません。読めないし書くことも困難です。

書き方を工夫して見やすくする(書きやすくする)

C++で長いメソッドチェインを行う場合は書き方を工夫すると見やすくなります。

// C++
a.b(7)
 .c(x.func())
 .d(7,x.func())
 .e(x.func().func())
 .f();

Objective-Cも書き方を工夫すれば…入れ子構造をインデントでわかりやすく…あれれ。

// Objective-C
[
  [
    [
      [
        [a b:7]
        c:[x func]
      ]
      d:7 param:[x func]
    ]
    e:[[x func] func]
  ]
  f
];

試行錯誤した結果、以下のような書き方になりました。

// Objective-C
[[[[                     // まずチェインの回数だけ左括弧を置く(この例では4個)
[ a b:7                  // 最初のメソッド呼び出し
] c: [x func]            // チェイン1回目
] d: 7 param:[x func]    // チェイン2回目
] e: [[x func] func]     // チェイン3回目
] f                      // チェイン4回目
];                       // 終わり

これでObjective−Cでもメソッドチェインが捗りますね。

他の方法

ブロックを使ってメソッドチェインを行う方法もあるようです。

Objective-Cでドット記法でメソッドを呼ぶ方法 - Islands in the byte stream