ReactiveCocoa(RAC)學習筆記

1、ReactiveCocoa開發中常見用法

  • 代替代理:

rac_signalForSelector:用于替代代理。

  • 代替KVO :

rac_valuesAndChangesForKeyPath:用于監聽某個對象的屬性改變。

  • 監聽事件:

    rac_signalForControlEvents:用于監聽某個事件。

  • 代替通知:

rac_addObserverForName:用于監聽某個通知。

  • 監聽文本框文字改變:

rac_textSignal:只要文本框發出改變就會發出這個信號。

2、ReactiveCocoa高級用法

  • Map

Map作用:把源信號的值映射成一個新的值
###### Map使用步驟:
1.傳入一個block,類型是返回對象,參數是value
2.value就是源信號的內容,直接拿到源信號的內容做處理
3.把處理好的內容,直接返回就好了,不用包裝成信號,返回的值,就是映射的值。

Map使用場景:

1.服務端返回的數據不是你需要的,需要進行一次二次加工,使用 map就會很方便

      [[_textField.rac_textSignal map:^id(id value) {
        // 當源信號發出,就會調用這個block,修改源信號的內容
        // 返回值:就是處理完源信號的內容。
        return [NSString stringWithFormat:@"輸出:%@",value];
    }] subscribeNext:^(id x) {

        NSLog(@"%@",x);
    }];
  • concat

concat:按一定順序拼接信號,當多個信號發出的時候,有順序的接收信號。

concat使用場景:

1.在工作中,有這樣的需求,可能一個頁面要發送幾個API,要求有一個API是依賴其他幾個API,等到所有API都成功之后在刷新UI

    RACSignal *signal1 = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        [subscriber sendNext:@1];
        [subscriber sendCompleted];
        return nil;
    }];
    
    RACSignal *signal2 = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        [subscriber sendNext:@2];
        [subscriber sendCompleted];

        return nil;
    }];
    RACSignal *signal3 = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        [subscriber sendNext:@"3"];
        [subscriber sendCompleted];

        return nil;
    }];
    
    //信號3依賴信號1和信號2
    RACSignal *signal = [[[RACSignal merge:@[signal1,signal2]]concat:signal3]   filter:^BOOL(id value) {
        return [value isKindOfClass:[NSNumber class]];
    }];
    
    [signal subscribeNext:^(id x) {
        NSLog(@"====%@",x);
    }completed:^{
        NSLog(@"所有都完事了");
    }];
log
2017-03-07 17:25:35.339 racDemo[61024:1544009] ====1
2017-03-07 17:25:35.340 racDemo[61024:1544009] ====2
2017-03-07 17:25:35.341 racDemo[61024:1544009] 所有都完事了

記得加         [subscriber sendCompleted];

  • Zip

zip:把兩個信號壓縮成一個信號,只有當兩個信號同時發出信號內容時,并且把兩個信號的內容合并成一個元組,才會觸發壓縮流的next事件。

   RACSignal *signal1 = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
       [subscriber sendNext:@1];
       [subscriber sendCompleted];
       return nil;
   }];
   
   RACSignal *signal2 = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
       [subscriber sendNext:@2];
       [subscriber sendCompleted];
       return nil;
   }];
   RACSignal *signal3 = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
       [subscriber sendNext:@"3"];
       [subscriber sendCompleted];
       return nil;
   }];

   RACSignal *signal = [RACSignal zip:@[signal1,signal2,signal3] reduce:^id(NSNumber *s1,NSNumber *s2,NSString *s3){
       return RACTuplePack(s1,s2,s3);
   }];
   
   [signal subscribeNext:^(RACTuple *tuple) {
       RACTupleUnpack(NSNumber *num1,NSNumber *num2,NSString *s3) = tuple;

       NSLog(@"%@%@%@",num1,num2,s3);
   }completed:^{
       NSLog(@"所有都完事了");
   }];
log
2017-03-07 17:38:57.227 racDemo[61197:1553408] 123
2017-03-07 17:38:57.227 racDemo[61197:1553408] 所有都完事了
tips:

1,記住要發送 [subscriber sendCompleted];
2,順序不要亂了,每一個信號對應一個返回,順序錯了,返回的值也就不對應了
3,sendNext只會走一次,如果有兩個sendNext,那么第二個發過來的值就不會生效
4,如果只要一個值,就沒有必要RACTuplePack了
eg:
[subscriber sendNext:@"3"];
[subscriber sendNext:@"100"];
[subscriber sendCompleted];
同樣代碼,在后面多加上一個sendNext 輸出結果如下
2017-03-07 17:44:17.808 racDemo[61350:1558976] 123
2017-03-07 17:44:17.808 racDemo[61350:1558976] 所有都完事了

  • combineLatest:

combineLatest將多個信號合并起來,并且拿到各個信號的最新的值,必須每個合并的signal至少都有過一次sendNext,才會觸發合并的信號。

RACSignal combineLatest:<#(id<NSFastEnumeration>)#> reduce:<#^id(void)reduceBlock#>
RACSignal combineLatest:<#(id<NSFastEnumeration>)#>

用法和zip reduce差不多,但是每次有最新的都會回調
  • filter:

// 過濾:
// 每次信號發出,會先執行過濾條件判斷.
[_textField.rac_textSignal filter:^BOOL(NSString *value) {
       return value.length > 3;
}];
  • doNext && doCompleted

[[[[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
  [subscriber sendNext:@1];
  [subscriber sendCompleted];
  return nil;
}] doNext:^(id x) {
// 執行[subscriber sendNext:@1];之前會調用這個Block
  NSLog(@"doNext");;
}] doCompleted:^{
   // 執行[subscriber sendCompleted];之前會調用這個Block
  NSLog(@"doCompleted");;

}] subscribeNext:^(id x) {

  NSLog(@"%@",x);
}];

  • interval

[[RACSignal interval:1 onScheduler:[RACScheduler currentScheduler]] subscribeNext:^(id x) {

 NSLog(@"%@",x);
}];
  • then

then:用于連接兩個信號,當第一個信號完成,才會連接then返回的信號。


// then:用于連接兩個信號,當第一個信號完成,才會連接then返回的信號
// 注意使用then,之前信號的值會被忽略掉.
// 底層實現:1、先過濾掉之前的信號發出的值。2.使用concat連接then返回的信號
[[[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {

 [subscriber sendNext:@1];
 [subscriber sendCompleted];
 return nil;
}] then:^RACSignal *{
 return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
     [subscriber sendNext:@2];
     return nil;
 }];
}] subscribeNext:^(id x) {

 // 只能接收到第二個信號的值,也就是then返回信號的值
 NSLog(@"%@",x);
}];
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • RAC使用測試Demo下載:github.com/FuWees/WPRACTestDemo 1.ReactiveC...
    FuWees閱讀 6,485評論 3 10
  • 1.ReactiveCocoa常見操作方法介紹。 1.1 ReactiveCocoa操作須知 所有的信號(RACS...
    萌芽的冬天閱讀 1,042評論 0 5
  • 前言 之前對RAC有了一個基本的認識,了解了它的作用,以及RAC的運行機制,我們知道只要是信號(RACSignal...
    大大盆子閱讀 4,518評論 0 11
  • 1.ReactiveCocoa常見操作方法介紹1.1 ReactiveCocoa操作須知所有的信號(RACSign...
    IIronMan閱讀 2,626評論 2 17
  • 一個奇怪的長長的夢 夢里我曾深深著迷的你 笑的酒窩那么深 和我的閨蜜竊語 遇見她我才深刻的體會了 什么是靈犀什么是...
    羽蒙張閱讀 168評論 0 0