2014-03-05 24 views
0

我想實現一個可以執行的RACCommand來啓動向UI顯示最新的可用數據。使用反應可可簡潔地獲取本地數據,然後用遠程數據更新

sendNext:調用將分別從本地數據庫和遠程服務器返回數據。

是否有更簡潔的方式來實現相同的行爲?

self.testObjects = @[ @"initial" ]; 

RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) { 
    RACSignal *s1 = [RACSignal createSignal:^RACDisposable *(id <RACSubscriber> subscriber) { 
     [subscriber sendNext:@[@"value1", @"value2"]]; 
     [subscriber sendCompleted]; 
     return [RACDisposable disposableWithBlock:^{ 
      // Cleanup 
     }]; 
    }]; 

    RACSignal *s2 = [RACSignal createSignal:^RACDisposable *(id <RACSubscriber> subscriber) { 
     [subscriber sendNext:@[ @"value1-updated", @"value2" ]]; 
     [subscriber sendCompleted]; 
     return [RACDisposable disposableWithBlock:^{ 
      // Cleanup 
     }]; 
    }]; 

    return [RACSignal createSignal:^RACDisposable *(id <RACSubscriber> subscriber) { 
     [s1 subscribeNext:^(id x) { 
      [subscriber sendNext:x]; 
     }]; 

     [s1 subscribeCompleted:^{ 
      [s2 subscribeNext:^(id x) { 
       [subscriber sendNext:x]; 
      }]; 
     }]; 

     return [RACDisposable disposableWithBlock:^{ 
      // Cleanup 
     }]; 
    }]; 
}]; 

RACSignal *racSignal = [command.executionSignals switchToLatest]; 
RAC(self, testObjects) = racSignal; 

[[self rac_valuesAndChangesForKeyPath:@"testObjects" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial observer:self] subscribeNext:^(RACTuple *x) { 
    RACTupleUnpack(NSArray *values) = x; 
    NSLog(@"values: %@", values); 
}]; 

[command execute:nil]; 

輸出:

值:( 初始 )

值:( 值1, VALUE2 )

值:( 「VALUE1更新的」, VALUE2 )

回答

1

假設您可以對s1s2(即假設您沒有任何全局清理,您沒有提及)中的每一個在一次性設備中執行所有清理,則可以使用-[RACSignal concat:]方法將這兩個信號加在一起:

RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) { 
    RACSignal *s1 = [RACSignal createSignal:^RACDisposable *(id <RACSubscriber> subscriber) { 
     [subscriber sendNext:@[@"value1", @"value2"]]; 
     [subscriber sendCompleted]; 
     return [RACDisposable disposableWithBlock:^{ 
      // Cleanup 
     }]; 
    }]; 

    RACSignal *s2 = [RACSignal createSignal:^RACDisposable *(id <RACSubscriber> subscriber) { 
     [subscriber sendNext:@[ @"value1-updated", @"value2" ]]; 
     [subscriber sendCompleted]; 
     return [RACDisposable disposableWithBlock:^{ 
      // Cleanup 
     }]; 
    }]; 

    return [s1 concat:s2]; 
}]; 

-[RACSignal concat:]方法在這種情況下將產生它提供上s1所有值的信號,並且然後當s1完成將兌現s2值,直到它完成(在該時間內返回的信號將完成)。

+0

感謝erik,這確實奏效,同時也暴露出我對RACCommand的執行信號如何與switchToLatest協同工作的困惑。我曾預料,由於concat信號完成testObjects只會更新一次,但這不會發生,我假設,因爲executionSignals沒有完成它只是發送下一個信號。 – nacross

+1

每次執行命令時,傳遞給' - [RACCommand initWithSignalBlock:]'的塊都會被調用。因此,從技術上講,concat'd信號*只更新'testObjects'一次,但每次執行該命令時都會創建一個新的concat'd信號,所以最終結果是'testObjects'被更新多次。 – erikprice

相關問題