(轉) ReactiveCocoa之RAC合併

weixin_33924312發表於2016-09-09
@interface ViewController ()  
@property (weak, nonatomic) IBOutlet UITextField *accountField;  
@property (weak, nonatomic) IBOutlet UITextField *pwdField;  
@property (weak, nonatomic) IBOutlet UIButton *loginBtn;  
  
@end  
  
@implementation ViewController  
  
- (void)viewDidLoad {  
    [super viewDidLoad];  
    // Do any additional setup after loading the view, typically from a nib.  
    [self concat];  
      
}  
  
// 把多個訊號聚合成你想要的訊號,使用場景----:比如-當多個輸入框都有值的時候按鈕才可點選。  
// 思路--- 就是把輸入框輸入值的訊號都聚合成按鈕是否能點選的訊號。  
- (void)combineLatest {  
      
    RACSignal *combinSignal = [RACSignal combineLatest:@[self.accountField.rac_textSignal, self.pwdField.rac_textSignal] reduce:^id(NSString *account, NSString *pwd){ //reduce裡的引數一定要和combineLatest陣列裡的一一對應。  
        // block: 只要源訊號傳送內容,就會呼叫,組合成一個新值。  
        NSLog(@"%@ %@", account, pwd);  
        return @(account.length && pwd.length);  
    }];  
      
    //    // 訂閱訊號  
    //    [combinSignal subscribeNext:^(id x) {  
    //        self.loginBtn.enabled = [x boolValue];  
    //    }];    // ----這樣寫有些麻煩,可以直接用RAC巨集  
    RAC(self.loginBtn, enabled) = combinSignal;  
      
      
    /* 
    RACSignal *signal = [RACSignal combineLatest:@[self.accountField.rac_textSignal,self.pwdField.rac_textSignal] reduce:^id(NSString *string1, NSString *string2){ 
         
        return @(string1.length && string2.length) ; 
         
    }]; 
     
     
     
    RAC(self.loginBtn,selected) = signal ; 
    */  
      
}  
  
  
- (void)zipWith {  
    //zipWith:把兩個訊號壓縮成一個訊號,只有當兩個訊號同時發出訊號內容時,並且把兩個訊號的內容合併成一個元祖,才會觸發壓縮流的next事件。  
    // 建立訊號A  
    RACSubject *signalA = [RACSubject subject];  
    // 建立訊號B  
    RACSubject *signalB = [RACSubject subject];  
    // 壓縮成一個訊號  
    // **-zipWith-**: 當一個介面多個請求的時候,要等所有請求完成才更新UI  
    // 等所有訊號都傳送內容的時候才會呼叫  
    RACSignal *zipSignal = [signalA zipWith:signalB];  
    [zipSignal subscribeNext:^(id x) {  
        NSLog(@"%@", x); //所有的值都被包裝成了元組  
    }];  
      
    // 傳送訊號 互動順序,元組內元素的順序不會變,跟傳送的順序無關,而是跟壓縮的順序有關[signalA zipWith:signalB]---先是A後是B  
    [signalA sendNext:@1];  
    [signalB sendNext:@2];  
  
}  
  
// 任何一個訊號請求完成都會被訂閱到  
// merge:多個訊號合併成一個訊號,任何一個訊號有新值就會呼叫  
- (void)merge {  
    // 建立訊號A  
    RACSubject *signalA = [RACSubject subject];  
    // 建立訊號B  
    RACSubject *signalB = [RACSubject subject];  
    //組合訊號  
    RACSignal *mergeSignal = [signalA merge:signalB];  
    // 訂閱訊號  
    [mergeSignal subscribeNext:^(id x) {  
        NSLog(@"%@", x);  
    }];  
    // 傳送訊號---交換位置則資料結果順序也會交換  
    [signalB sendNext:@"下部分"];  
    [signalA sendNext:@"上部分"];  
}  
  
// then --- 使用需求:有兩部分資料:想讓上部分先進行網路請求但是過濾掉資料,然後進行下部分的,拿到下部分資料  
- (void)then {  
    // 建立訊號A  
    RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {  
        // 傳送請求  
        NSLog(@"----傳送上部分請求---afn");  
          
        [subscriber sendNext:@"上部分資料"];  
        [subscriber sendCompleted]; // 必須要呼叫sendCompleted方法!  
        return nil;  
    }];  
      
    // 建立訊號B,  
    RACSignal *signalsB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {  
        // 傳送請求  
        NSLog(@"--傳送下部分請求--afn");  
        [subscriber sendNext:@"下部分資料"];  
        [subscriber sendCompleted];  
        return nil;  
    }];  
    // 建立組合訊號  
    // then;忽略掉第一個訊號的所有值  
    RACSignal *thenSignal = [signalA then:^RACSignal *{  
        // 返回的訊號就是要組合的訊號  
        return signalsB;  
    }];  
      
    // 訂閱訊號  
    [thenSignal subscribeNext:^(id x) {  
        NSLog(@"%@", x);  
    }];  
  
}  
  
// concat----- 使用需求:有兩部分資料:想讓上部分先執行,完了之後再讓下部分執行(都可獲取值)  
- (void)concat {  
    // 組合  
      
    // 建立訊號A  
    RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {  
        // 傳送請求  
        //        NSLog(@"----傳送上部分請求---afn");  
          
        [subscriber sendNext:@"上部分資料"];  
        [subscriber sendCompleted]; // 必須要呼叫sendCompleted方法!  
        return nil;  
    }];  
      
    // 建立訊號B,  
    RACSignal *signalsB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {  
        // 傳送請求  
        //        NSLog(@"--傳送下部分請求--afn");  
        [subscriber sendNext:@"下部分資料"];  
        return nil;  
    }];  
      
      
    // concat:按順序去連結  
    //**-注意-**:concat,第一個訊號必須要呼叫sendCompleted  
    // 建立組合訊號  
    RACSignal *concatSignal = [signalA concat:signalsB];  
    // 訂閱組合訊號  
    [concatSignal subscribeNext:^(id x) {  
        NSLog(@"%@",x);  
    }];  
  
}  

注:轉載自http://blog.csdn.net/y_csdnblog_xx/article/details/51480563

相關文章