日々精進

新しく学んだことを書き留めていきます

Reactive CocoaでViewを更新する時はthrottle:0する

Reactive CocoaでViewとViewModelをBindすると、ViewModelのプロパティを変更する度にViewの更新ロジックが実行されるのでパフォーマンスに問題が出やすい。
特にTableViewは以下のようにViewModelの配列のどこかを変更されたら都度reloadとしていると一回のRunLoopで何十回とreloadされる。

- (void)setCurrencyPairSettingViewModels:(CurrencyPairSettingViewModelCollection *)currencyPairSettingViewModels {
    _currencyPairSettingViewModels = currencyPairSettingViewModels;
    [self.currencyPairTableView reloadData];
    [self.currencyPairSettingViewModels.changeSignal subscribeNext:^(id x) {
        [self.currencyPairSettingViewModels sort];
        [self.currencyPairTableView reloadData];
    }];
}

throttleは指定秒間以下の間隔でシグナルが連続して来たらそれを無視するというメソッドなので、これを使うとRunLoop毎に一度だけViewの更新処理を実行させられる。

- (void)setCurrencyPairSettingViewModels:(CurrencyPairSettingViewModelCollection *)currencyPairSettingViewModels {
    _currencyPairSettingViewModels = currencyPairSettingViewModels;
    [self.currencyPairTableView reloadData];
    [[self.currencyPairSettingViewModels.changeSignal throttle:0] subscribeNext:^(id x) {
        [self.currencyPairSettingViewModels sort];
        [self.currencyPairTableView reloadData];
    }];
}