Skip to main content
distinctUntilChanged 
の使いどころ 
安宅正之 at ChatWork 株式会社 
2014/10/18 (Sat)
自己紹介 
• 安宅 正之 (あたか まさゆき / @at_aka) 
• 2014/04 より ChatWork株式会社 モバイルチーム 
• https://github.com/ataka 
• Blog: clmemo@aka http://at-aka.blogspot.com
状態管理フラグの 
変更を知りたいなら 
[RACObserve(self.viewModel, canFoo) 
distinctUntilChanged]; 
distinctUntilChanged が便利
One-to-One 
RAC(self.foo, enable) 
= RACObserve(self.viewModel, canFoo); 
• View と ViewModel の property が一対一対応
変換が必要な場合 
RAC(self.foo, title) 
= [RACObserve(self.viewModel, canFoo) 
map:^(NSNumber* enableNum) { 
BOOL enable = enableNum.boolValue; 
return (enable ? @“Foo” : @“Bar”); 
}]; 
• map で変換します
subscribeNext も使えます 
[RACObserve(self.viewModel, canFoo) 
subscribeNext:^(NSNumber* enableNum) { 
BOOL enable = enableNum.boolValue; 
self.foo = (enable ? @“Foo” : @“Bar”); 
}]; 
• property を代入できない場合も便利です 
[self.bar setTitle:@“Foo”]; 
• 循環参照が怖いです
循環参照が怖いです
rac_liftSelector 
[self 
rac_liftSelector:@selector(setFooTitle:) 
withSignals:RACObserve(self.viewModel, canFoo), 
nil]; 
! 
- (void)setFooTitle:(BOOL)enable 
{ 
self.foo.title = (enable ? @“Foo” : @“Bar”); 
} 
• weakSelf いらず。循環参照の恐怖から解放 
• コードの可読性アップ!
RACSignal* を外に出す 
RACSignal* canFooSignal = 
RACObserve(self.viewModel, canFoo); 
[self rac_liftSelector:@selector(setFooTitle:) 
withSignals:canFooSignal, nil]; 
! 
- (void)setFooTitle:(BOOL)enable { … } 
• Signal が再利用可能になりました
宣伝 
ChatWork にはライブ機能 
があります
ChatWork Live プラン 
ビデオチャット 
制限人数音声チャット 
フリー2 人YES 
パーソナル4 人YES 
ビジネス14 人YES
仕様 
• プランはライブ・ユーザーの中で最も高いプランが 
適用される 
• 制限人数を越えると、音声チャットへ移行する
ビデオ・ビュー 
カメラ ON/OFF 
フロント/バック・トグル
一つのシグナルで複数の処理 
RACSignal* canVideoChatSignal = 
RACObserve(self.viewModel, canVideoChat); 
[self.cameraOnButton // Camera ON/OFF 
rac_liftSelector:@selector(setEnabled:) 
withSignals:canVideoChatSignal, nil]; 
[self.cameraChangeButton // Front/Back Camera 
rac_liftSelector:@selector(setEnabled:) 
withSignals:canVideoChatSignal, nil]; 
[self rac_liftSelector:@selector(setVideo:) 
withSignals:canVideoChatSignal, nil]; 
! 
- (void)setVideo:(BOOL)canVideoChat { … }
構成 
View ViewModel Model 
ユーザーのプランを確認 
ビデオチャット可能かPlanManagerModel 
cなa?nVideoChat 
ユーザーが入室しました 
ユーザーが入室しました 
ServiceModel 
ReactiveCocoa 
Storyboard LiveViewModel 
LiveViewController 
ユーザー入室 
viewModel.canVideoChat 
ユーザー入室 
ユーザーが入室するたびに RACSignal が飛ぶ
シグナルを 
変更された時にだけ 
受け取りたい
それ 
distinctUntilChanged 
で出来るよ
修正版シグナル 
RACSignal* canVideoChatSignal = 
[RACObserve(self.viewModel, canVideoChat) 
distinctUntilChanged]; 
安全なシグナルができました
まとめ 
1. 処理が複雑になるなら rac_liftSelector を使う 
2. 複数の処理に別れるなら RACSignal* を作る 
3. シグナルの変更だけ知りたければ 
distinctUntilChanged を使う
ご清聴 
ありがとうございます