RACSequence
とRACStream
は3.0でDeprecateになる予定になっており、
コレクション周りの処理を行いたければ、Underscore.mやRXCollectionsなどのサードパーティライブラリを使ってね、ということになりました (ちなみに、現時点でのReactiveCocoaの安定版は2.0なので、3.0は開発版です)。
これによって、RACSequence
とRACStream
にあったメソッドがRACSignal
に移動して、コードも非常にわかりやすくなりました。
今回はその例として、concat:
とcatch:
のコードを見てみます。
concat:
とcatchTo:
の動作について
簡単に言うと、concat:
とcatchTo:
はどちらも2つのシグナルをくっつけてひとつのシグナルに見せかけます。
そのくっつける条件が異なっていて、レシーバであるシグナルオブジェクトが、CompletedとErrorのどちらのイベントで終わるかで決まります。
concat:
はレシーバがCompletedイベントで終わるなら、くっつけるcatchTo:
はレシーバがErrorイベントで終わるなら、くっつける
具体的な例で見てみましょう。例えば、次の3つのシグナルがあったとします。
- シグナル
AC
はnextイベントx
とnextイベントy
を送信したあとに、Completedイベントで終わる (これをAC
::=
x
→y
→ Completedと表すことにします) - シグナル
AE
::=
x
→y
→ Error - シグナル
B
::=
z
→ Completed
このとき、これらをconcat:
とcatchTo:
で結合したシグナルは、それぞれ次のような結果が得られます。
[AC concat:B]
::=
x
→y
→z
→ Completed[AE concat:B]
::=
x
→y
→ Error[AC catchTo:B]
::=
x
→y
→ Completed[AE catchTo:B]
::=
x
→y
→z
→ Completed
コード
ではコードを見ていきましょう。なお、以下のコードでは説明に不要な個所はオリジナルコードから省いています。
concat:
最初5行くらいは無視して、next:
あたりからのコードに注目してください。
1 2 3 4 5 6 7 8 9 10 11 12 13 | - ( RACSignal *)concat:( RACSignal *)signal { return [ RACSignal create :^( id <RACSubscriber> subscriber) { [ self subscribeSavingDisposable :^( RACDisposable *disposable) { [subscriber .disposable addDisposable :disposable]; } next :^( id x) { [subscriber sendNext :x]; } error :^( NSError *error) { [subscriber sendError :error]; } completed :^{ [signal subscribe :subscriber]; }]; }]; } |
nextイベントとerrorイベントはただ転送しているだけですが、completedイベントについては、引数のシグナルに繋げていることがわかります。
catch:
このメソッドは上のconcat:
と似ていることに気付いたでしょうか? 違う点は引数の型がblockになっていることと、
errorイベントとcompletedイベントあたりの処理がconcat:
とは逆になっていることです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | - ( RACSignal *)catch:( RACSignal * (^)( NSError *error))catchBlock { return [ RACSignal create :^( id <RACSubscriber> subscriber) { [ self subscribeSavingDisposable :^( RACDisposable *disposable) { [subscriber .disposable addDisposable :disposable]; } next :^( id x) { [subscriber sendNext :x]; } error :^( NSError *error) { RACSignal *signal = catchBlock(error); [signal subscribe :subscriber]; } completed :^{ [subscriber sendCompleted ]; }]; }]; } |
catch:
では、nextイベントとcompletedイベントはただ転送しているだけですが、errorイベントについては、引数のblockが生成するシグナルに繋げていることがわかります。
最初の説明に出てきていたcatchTo:
は、このcatch:
を使って実現されています。
catchTo:
このコードはReactiveCocoa 2.0と同じです。
1 2 3 4 5 | - ( RACSignal *)catchTo:( RACSignal *)signal { return [ self catch :^( NSError *error) { return signal; }]; } |
おわりに
ReactiveCocoa 3.0のconcat:
とcatch:
のコードを簡単に紹介しました。
0 件のコメント:
コメントを投稿
注: コメントを投稿できるのは、このブログのメンバーだけです。