これを行う 1 つの方法は次のとおりです。ロック上の各ホイールの現在の値を表す NSNumbers の信号とsuccessIndicator
、組み合わせが正しいかどうかを示すものがあると仮定します。
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);
};
すべての入力がシグナルとして表されると、通常の操作 (値を操作する) を RAC 操作 (値のストリームを操作する) に置き換えて、標準の Objective-C で行うように大まかに進めることができます。
各操作は、値のストリームを別の値のストリームに変換するステップを表します。各ステップは、最初の値のストリームを必要な値のストリームに変換する次のステップを表す新しいシグナルになります。
関連して、最後の操作には出力信号がなく、副作用を引き起こす唯一の場所です。値を変換および結合するロジックと、副作用を実行するロジックを分離することをお勧めします。このようにして、ロックされたシグナルにオブザーバーを追加したり、意図しない結果を心配することなくロックされたコードに影響を与えるコードをリファクタリングしたりできます。
次の課題は、正しい組み合わせへの変更、またはロックの車輪の数を処理することです。