下面是做这件事的一种方法:假设你有代表对锁的每个车轮和successIndicator
的当前值NSNumbers的信号指示组合是否是正确的:
NSArray *correctCombination = @[@1, @2, @3, @4)];
RACSignal *currentCombination = [RACSignal combineLatest:@[digit1, digit2, digit3, digit4];
RACSignal *(^hasCorrectValue)(NSUInteger idx) ^(NSUInteger idx){
return [currentCombination map:^(RACTuple *currentCombination) {
return [currentCombination[idx] isEqual:correctCombination[idx]];
}];
};
__block RACSignal *(^hasUnlockedStage)(NSUInteger idx) = ^(NSUInteger idx){
if (idx == 0) return hasCorrectValue(idx);
else return [hasCorrectValue(idx) and:hasUnlockedStage(idx - 1)];
};
[hasUnlockedStage(0) setKeypath:@keypath(wheel2, enabled) onObject:wheel2];
[hasUnlockedStage(1) setKeypath:@keypath(wheel3, enabled) onObject:wheel3];
[hasUnlockedStage(2) setKeypath:@keypath(wheel4, enabled) onObject:wheel4];
[hasUnlockedStage(3) setKeypath:@keypath(successIndicator, active) onObject:successIndicator];
hasUnlockedStage = nil; // nil out recursive block
中间部分,其中逻辑发生,是非常相似的非反应性:
BOOL(^hasCorrectValue)(NSUInteger idx) ^(NSUInteger idx){
return [[views[idx] currentValue] isEqual:[correctCombination[idx] currentValue]];
};
__block BOOL(^hasUnlockedStage)(NSUInteger idx) = ^(NSUInteger idx){
if (idx == 0) return hasCorrectValue(idx);
else return hasCorrectValue(idx) && hasUnlockedStage(idx - 1);
};
一旦所有的输入被表示为信号,可以大致如我们将在标准Objective-C的进行,代替RAC操作(其操作在值流上)用于正常操作(按值操作)。
每个操作表示将值流转换为另一个值流的步骤。每一步都会产生一个新的信号,它代表将我们的初始值流转换为我们想要的值流的进一步步骤。
相关地,最后一个操作没有输出信号,只是我们引起任何副作用的地方。分离转换和组合值的逻辑和执行副作用的逻辑是一种很好的做法。这样,我们可以为锁定的信号添加额外的观察者,或者重构影响锁定的代码,而不用担心意外的后果。
一个不错的下一个练习是处理对正确组合的更改或锁上车轮的数量。
看起来像我在你的问题的中间掠过。已经更新了我的答案! –