元ネタ: How to obtain KVO old value using ReactiveCocoa 2.0 API? · Issue #762 · ReactiveCocoa/ReactiveCocoa
KVOのオプションを使用する場合
ReactiveCocoaではRACObserve()
マクロによってKVOを非常に簡単に扱うことができますが、それだけでは、通常のKVOで使用するaddObserver:forKeyPath:options:context:
の場合には指定できるNSKeyValueObservingOptions
(NSKeyValueObservingOptionOldなど) を指定できません。
KVOのオプション指定を行いたい場合、-[NSObject rac_valuesAndChangesForKeyPath:options:observer:]
を使用するとKVOのオプション指定を反映したシグナルを得ることができます。ただし、この戻り値のシグナルはRACObserve()
とは違い、next
として、変更後の値とチェンジディクショナリーからなるRACTuple
を送るため、-reduceEach:
を使用するなどしてタプルの値を分解・チェンジディクショナリーから変更前の値を取得するなどの必要があります。
[[self
rac_valuesAndChangesForKeyPath:keyPath options:NSKeyValueObservingOptionOld observer:nil]
reduceEach:^(id value, NSDictionary *changeDictionary) {
id oldValue = changeDictionary[NSKeyValueChangeOldKey];
return // 何かしらの値;
}];
オペレーターを使用する場合
-[RACSignal combinePreviousWithStart:reduce:]
を使用すると、reduce:
のブロック引数で以下のように直前の値を使用することができます。
RACSignal *signal = [@[ @1, @2, @3, @4 ].rac_sequence signal];
[[signal
// 最初の`next`では`previous`に1つ目の引数(この場合は`@0`)が渡され、
// 2回目以降の`next` では前回の`current`が渡される。
combinePreviousWithStart:@0 reduce:^(NSNumber *previous, NSNumber *current) {
return @(previous.integerValue + current.integerValue);
}]
subscribeNext:^(NSNumber *value) {
NSLog(@"%d", value.integerValue);
}];
// 1 (<= 0 + 1)
// 3 (<= 1 + 2)
// 5 (<= 2 + 3)
// 7 (<= 3 + 4)