ReactiveCocoa 入門(mén)知識(shí)——?dú)w總篇


ReactiveCocoa (RAC) 是一個(gè)Cocoa框架了赵,受Functional Reactive Programming啟發(fā)。它提供Api合成變換(composing and transforming)隨著時(shí)間改變的數(shù)據(jù)流冗酿。
介紹


ReactiveCocoa來(lái)源于functional reactive programming(Input and Output)裁替。區(qū)別于使用不斷變化修改的變量弱判,RAC提供了“事件流”锥惋,通過(guò) SignalSignalProducer 類(lèi)型來(lái)表示, 它們隨著時(shí)間發(fā)送值膀跌。事件流統(tǒng)一了Cocoa用于事件和異步處理的常用模式捅伤,包括:
委托方法
回調(diào)blocks
通知
控件的actions和響應(yīng)事件鏈
Futures and promises
Key-value observing (KVO)

因?yàn)檫@些不同的機(jī)制能夠用一種相同的方式處理,可以很容易的聲明成鏈(chain)并且把它們聯(lián)合在一起困介,用更少的代碼和狀態(tài)連接它們。
基本使用


1.創(chuàng)建信號(hào)

方法1:

   RACSubscriber:表示訂閱者的意思粮彤,用于發(fā)送信號(hào)姜骡,這是一個(gè)協(xié)議圈澈,不是一個(gè)類(lèi)康栈,只要遵守這個(gè)協(xié)議喷橙,并且實(shí)現(xiàn)方 v     法才 能成為訂閱者贰逾。通過(guò)create創(chuàng)建的信號(hào)疙剑,都有一個(gè)訂閱者践叠,幫助他發(fā)送數(shù)據(jù)禁灼。
 RACDisposable:用于取消訂閱或者清理資源,當(dāng)信號(hào)發(fā)送完成或者發(fā)送錯(cuò)誤的時(shí)候哮独,就會(huì)自動(dòng)觸發(fā)它皮璧。
RACSignal *siganl = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
    // block調(diào)用時(shí)刻:每當(dāng)有訂閱者訂閱信號(hào)悴务,就會(huì)調(diào)用block讯檐。
    // 2.發(fā)送信號(hào)
    [subscriber sendNext:@1];
    // 如果不在發(fā)送數(shù)據(jù)染服,發(fā)送信號(hào)完成柳刮,內(nèi)部會(huì)自動(dòng)調(diào)用[RACDisposable disposable]取消訂閱信號(hào)秉颗。
    [subscriber sendCompleted];
    return [RACDisposable disposableWithBlock:^{
        // block調(diào)用時(shí)刻:當(dāng)信號(hào)發(fā)送完成或者發(fā)送錯(cuò)誤,就會(huì)自動(dòng)執(zhí)行這個(gè)block,取消訂閱信號(hào)哪替。
        // 執(zhí)行完Block后凭舶,當(dāng)前信號(hào)就不在被訂閱了库快。
        NSLog(@"信號(hào)被銷(xiāo)毀");
    }];
}];
// 3.訂閱信號(hào),才會(huì)激活信號(hào).
[siganl subscribeNext:^(id x) {
    // block調(diào)用時(shí)刻:每當(dāng)有信號(hào)發(fā)出數(shù)據(jù),就會(huì)調(diào)用block.
    NSLog(@"接收到數(shù)據(jù):%@",x);
}];
   2017-06-06 16:34:27.387 ReactiveCocoaDome[17827:6819312] 接收到數(shù)據(jù):1
   2017-06-06 16:34:27.387 ReactiveCocoaDome[17827:6819312] 信號(hào)被銷(xiāo)毀

方法2:

 // 1.創(chuàng)建信號(hào)
  RACSubject *subject = [RACSubject subject];
 // 2.訂閱信號(hào)
  [subject subscribeNext:^(id x) {
    // block調(diào)用時(shí)刻:當(dāng)信號(hào)發(fā)出新值,就會(huì)調(diào)用.
    NSLog(@"第一個(gè)訂閱者%@",x);
 }];
 [subject subscribeNext:^(id x) {
    // block調(diào)用時(shí)刻:當(dāng)信號(hào)發(fā)出新值蝶怔,就會(huì)調(diào)用.
    NSLog(@"第二個(gè)訂閱者%@",x);
}];
// 3.發(fā)送信號(hào)
 [subject sendNext:@"1"];
2017-06-06 16:34:27.388 ReactiveCocoaDome[17827:6819312] 第一個(gè)訂閱者1
2017-06-06 16:34:27.388 ReactiveCocoaDome[17827:6819312] 第二個(gè)訂閱者1

方法3:

  // RACReplaySubject使用步驟:
  // 1.創(chuàng)建信號(hào) [RACSubject subject]踢星,跟RACSiganl不一樣隙咸,創(chuàng)建信號(hào)時(shí)沒(méi)有block五督。
  // 2.可以先訂閱信號(hào),也可以先發(fā)送信號(hào)副签。
  // 2.1 訂閱信號(hào) - (RACDisposable *)subscribeNext:(void (^)(id x))nextBlock
  // 2.2 發(fā)送信號(hào) sendNext:(id)value
  // RACReplaySubject:底層實(shí)現(xiàn)和RACSubject不一樣淆储。
  // 1.調(diào)用sendNext發(fā)送信號(hào)本砰,把值保存起來(lái)灌具,然后遍歷剛剛保存的所有訂閱者譬巫,一個(gè)一個(gè)調(diào)用訂閱者的nextBlock芦昔。
  // 2.調(diào)用subscribeNext訂閱信號(hào)咕缎,遍歷保存的所有值凭豪,一個(gè)一個(gè)調(diào)用訂閱者的nextBlock
  // 如果想當(dāng)一個(gè)信號(hào)被訂閱,就重復(fù)播放之前所有值孔厉,需要先發(fā)送信號(hào)撰豺,在訂閱信號(hào)污桦。
  // 也就是先保存值匙监,在訂閱值亭姥。

// 1.創(chuàng)建信號(hào)
RACReplaySubject *replaySubject = [RACReplaySubject subject];

// 2.發(fā)送信號(hào)
[replaySubject sendNext:@1];
[replaySubject sendNext:@2];
[replaySubject sendCompleted];

// 3.訂閱信號(hào)
[replaySubject subscribeNext:^(id x) {
    
    NSLog(@"第一個(gè)訂閱者接收到的數(shù)據(jù)%@",x);
}];

// 訂閱信號(hào)
[replaySubject subscribeNext:^(id x) {
    
    NSLog(@"第二個(gè)訂閱者接收到的數(shù)據(jù)%@",x);
}];


RACDisposable * dispose = [RACDisposable disposableWithBlock:^{
    NSLog(@"replaySubject 銷(xiāo)毀了");
  
}];
RACCompoundDisposable * compoundDispose = [RACCompoundDisposable compoundDisposableWithDisposables:@[dispose]];
[replaySubject didSubscribeWithDisposable:compoundDispose];
 2017-06-06 16:34:27.550 ReactiveCocoaDome[17827:6819312] 第一個(gè)訂閱者接收到的數(shù)據(jù)1
 2017-06-06 16:34:27.550 ReactiveCocoaDome[17827:6819312] 第一個(gè)訂閱者接收到的數(shù)據(jù)2
 2017-06-06 16:34:27.551 ReactiveCocoaDome[17827:6819312] 第二個(gè)訂閱者接收到的數(shù)據(jù)1
 2017-06-06 16:34:27.551 ReactiveCocoaDome[17827:6819312] 第二個(gè)訂閱者接收到的數(shù)據(jù)2
 2017-06-06 16:34:27.551 ReactiveCocoaDome[17827:6819312] replaySubject 銷(xiāo)毀了

當(dāng)然 RACReplaySubject *replaySubject = [RACReplaySubject replaySubjectWithCapacity:1];
通過(guò)這種方式創(chuàng)建的 則指定了默認(rèn)的儲(chǔ)存值是1個(gè)
打印的 則為

 2017-06-06 16:51:00.570 ReactiveCocoaDome[18117:6914095] 第一個(gè)訂閱者接收到的數(shù)據(jù)2
 2017-06-06 16:51:00.570 ReactiveCocoaDome[18117:6914095] 第二個(gè)訂閱者接收到的數(shù)據(jù)2
2.針對(duì)不同對(duì)象的基本使用方法
  • UIButton
    添加事件
    [[_pushbut rac_signalForControlEvents:UIControlEventTouchUpInside]subscribeNext:^(id x) {
    @strongify(self);
    SendViewController *sendV = [[UIStoryboard storyboardWithName:@"Main" bundle:nil]instantiateViewControllerWithIdentifier:@"SendViewController"];
    sendV.delegateSingal = [RACSubject subject];
    [sendV.delegateSingal subscribeNext:^(id x) {
    NSLog(@"點(diǎn)擊了通知按鈕 %@",x);
    }];
    [self.navigationController pushViewController:sendV animated:YES]变抽;
    }];
    觸發(fā)信號(hào)

     _pushbut.rac_command = [[RACCommand alloc]initWithSignalBlock:^RACSignal *(id input) {
      return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
         [subscriber sendNext:@"發(fā)送數(shù)據(jù)"];
         
         // 注意:數(shù)據(jù)傳遞完绍载,最好調(diào)用sendCompleted侣夷,這時(shí)命令才執(zhí)行完畢逢并。
         [subscriber sendCompleted];
          return [RACDisposable disposableWithBlock:^{     
         }];
        }];
      }];
    
  • NSArray
    NSArray *numbers = @[@1,@2,@3,@4];
    // 這里其實(shí)是三步
    // 第一步: 把數(shù)組轉(zhuǎn)換成集合RACSequence numbers.rac_sequence
    // 第二步: 把集合RACSequence轉(zhuǎn)換RACSignal信號(hào)類(lèi),numbers.rac_sequence.signal
    // 第三步: 訂閱信號(hào)螃概,激活信號(hào),會(huì)自動(dòng)把集合中的所有值训貌,遍歷出來(lái)递沪。
    [numbers.rac_sequence.signal subscribeNext:^(id x) {
    NSLog(@"數(shù)組元素 %@",x);
    }];

  • NSDictionary
    NSDictionary *dict = @{@"name":@"xmg",@"age":@18};
    [dict.rac_sequence.signal subscribeNext:^(RACTuple *x) {

      // 解包元組款慨,會(huì)把元組的值檩奠,按順序給參數(shù)里面的變量賦值
      RACTupleUnpack(NSString *key,NSString *value) = x;
        // 相當(dāng)于以下寫(xiě)法
      //        NSString *key = x[0];
      //        NSString *value = x[1];
      NSLog(@"元組對(duì)象 x == %@", x);
      NSLog(@"字典轉(zhuǎn)化為 %@ %@",key,value);
     }];
    

*字典轉(zhuǎn)模型 RAC高級(jí)寫(xiě)法 *

  // map:映射的意思笆凌,目的:把原始值value映射成一個(gè)新值
  // array: 把集合轉(zhuǎn)換成數(shù)組
  // 底層實(shí)現(xiàn):當(dāng)信號(hào)被訂閱,會(huì)遍歷集合中的原始值送悔,映射成新值欠啤,并且保存到新的數(shù)組里洁段。
  NSArray *MMs = [[dictArr.rac_sequence map:^id(id value) {
     return [MM MMwithDic:value];
     }] array];
  • NSNotificationCenter

    [[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardWillShowNotification object:nil]     
     subscribeNext:^(id x) {
      NSLog(@"鍵盤(pán)彈出");
     }];
    
  • UITextField
    [textF.rac_textSignal subscribeNext:^(id x) {
    NSLog(@"文字改變了%@",x);
    }];

  • 定時(shí)器

    //創(chuàng)建定時(shí)器信號(hào)祠丝,定時(shí)8個(gè)小時(shí)
      RACSignal *signal = [RACSignal interval:60*60*8
                                  onScheduler:[RACScheduler mainThreadScheduler]];
      //定時(shí)執(zhí)行代碼
      [signal subscribeNext:^(id x) {
          NSLog(@"吃藥");
      }];
    
      RACSignal *singal = [[[[[RACSignal interval:1 onScheduler [RACSchedulerscheduler]]take:10]startWith:@(1)]map:^id(id value) {
      NSLog(@"%@",value);
      return @"發(fā)送出去的信號(hào)";
      }]takeUntil:self.rac_willDeallocSignal];
     [singal subscribeNext:^(id x) {
      NSLog(@"x == %@",x);
     }];
    
  • 代理
    @protocol ProgrammerDelegate
    - (void)makeAnApp;
    @end

    //為self添加一個(gè)信號(hào)写半,表示代理ProgrammerDelegate的makeAnApp方法信號(hào)
     RACSignal *programmerSignal = [self rac_signalForSelector:@selector(makeAnApp)
                                               fromProtocol:@protocol(ProgrammerDelegate)];
     //設(shè)置代理方法makeAnApp的實(shí)現(xiàn)
     [programmerSignal subscribeNext:^(RACTuple* x) {
        //這里可以理解為makeAnApp的方法要的執(zhí)行代碼
        NSLog(@"花了一個(gè)月叠蝇,app寫(xiě)好了");
    }];
    //調(diào)用代理方法
    [self makeAnApp];
    
3.其他常用
  • 觀(guān)察值的變化 (監(jiān)控屬性等 MVVM 中比較常用)

    @weakify(self);
     [RACObserve(self, value)subscribeNext:^(id x) {
      @strongify(self);
      NSLog(@"value 發(fā)生了變化%@",self.value);
      }];
    
  • 改變信號(hào)中的值
    RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
    [subscriber sendNext:@"跳舞"];
    [subscriber sendCompleted];
    return [RACScopedDisposable disposableWithBlock:^{

      }];
      }];
    //對(duì)信號(hào)進(jìn)行改進(jìn)
     RAC(self,value) = [signalA map:^id(id value) {
      if ([value isEqualToString:@"跳舞"]) {
          return @"唱歌";
      }
      return @"";
    }];
    
  • 廣播 通知

    NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
    //注冊(cè)廣播通知
    RACSignal *signal = [center rac_addObserverForName:@"代碼之道頻道" object:nil];
     //設(shè)置接收到通知的回調(diào)處理
    [signal subscribeNext:^(NSNotification* x) {
      NSLog(@"技巧:%@", x.userInfo[@"技巧"]);
      }];
     //發(fā)送廣播通知
     [center postNotificationName:@"代碼之道頻道"
                        object:nil
                      userInfo:@{@"技巧":@"用心寫(xiě)"}];
    
  • 串聯(lián) 并聯(lián)
    //創(chuàng)建一個(gè)信號(hào)管A
    {
    RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id subscriber) {
    //發(fā)送一個(gè)Next玻璃球和一個(gè)Complete玻璃球
    [subscriber sendNext:@"我戀愛(ài)啦"];
    [subscriber sendCompleted];
    return nil;
    }];
    //創(chuàng)建一個(gè)信號(hào)管B
    RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id subscriber) {
    //發(fā)送一個(gè)Next玻璃球和一個(gè)Complete玻璃球
    [subscriber sendNext:@"我結(jié)婚啦"];
    [subscriber sendCompleted];
    return nil;
    }];
    //串聯(lián)管A和管B
    RACSignal *concatSignal = [signalA concat:signalB];
    //串聯(lián)后的接收端處理
    [concatSignal subscribeNext:^(id x) {
    NSLog(@"%@",x);
    }];
    //打印:我戀愛(ài)啦 我結(jié)婚啦

     }
     {
      //創(chuàng)建信號(hào)A
      RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id subscriber) {
          [subscriber sendNext:@"紙廠(chǎng)污水"];
          return nil;
      }];
      //創(chuàng)建信號(hào)B
      RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id subscriber) {
          [subscriber sendNext:@"電鍍廠(chǎng)污水"];
          return nil;
      }];
      //并聯(lián)2個(gè)信號(hào)
      RACSignal *mergeSignal = [RACSignal merge:@[signalA, signalB]];
      [mergeSignal subscribeNext:^(id x) {
          NSLog(@"處理%@",x);
      }];
     }
    
  • 組合
    {
    //定義2個(gè)自定義信號(hào)
    RACSubject *letters = [RACSubject subject];
    RACSubject *numbers = [RACSubject subject];
    //組合信號(hào)
    [[RACSignal combineLatest:@[letters, numbers]
    reduce:^(NSString *letter, NSString *number){
    //把2個(gè)信號(hào)的信號(hào)值進(jìn)行字符串拼接
    return [letter stringByAppendingString:number];
    }] subscribeNext:^(NSString * x) {
    NSLog(@"%@", x);
    }];
    //自己控制發(fā)送信號(hào)值
    [letters sendNext:@"A"];
    [letters sendNext:@"B"];
    [numbers sendNext:@"1"];//打印B1
    [letters sendNext:@"C"];//打印C1
    [numbers sendNext:@"2"];//打印C2
    }

  • 映射
    //創(chuàng)建信號(hào),發(fā)送"石"玻璃球
    RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id subscriber) {
    [subscriber sendNext:@"石"];
    return nil;
    }];
    //對(duì)信號(hào)進(jìn)行改造蛇损,改造"石"為"金"
    signal = [signal map:^id(NSString *value) {
    if ([value isEqualToString:@"石"]) {
    return @"金";
    }
    return value;
    }];
    打印
    [signal subscribeNext:^(id x) {
    NSLog(@"%@", x);//金
    }];

  • 過(guò)濾

    //創(chuàng)建信號(hào)
      RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id subscriber) {
          [subscriber sendNext:@(15)];
          [subscriber sendNext:@(17)];
          [subscriber sendNext:@(21)];
          [subscriber sendNext:@(14)];
          [subscriber sendNext:@(30)];
          return nil;
      }];
      //過(guò)濾信號(hào)淤齐,并打印
      [[signal filter:^BOOL(NSNumber* value) {
          //值大于等于18的才能通過(guò)過(guò)濾網(wǎng)
          return value.integerValue >= 18;
      }] subscribeNext:^(id x) {
          NSLog(@"%@", x);
      }];
      //打痈摹:21 30
    
  • 命令
    //創(chuàng)建命令
    RACCommand *aCommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(NSString *input) {
    //命令執(zhí)行代碼
    NSLog(@"%@我投降了",input);
    //返回一個(gè)RACSignal信號(hào)
    return [RACSignal createSignal:^RACDisposable *(id subscriber) {
    [subscriber sendCompleted];
    return nil;
    }];
    }];
    //執(zhí)行命令
    [aCommand execute:@"今天"];
    //打蛹牢瘛:今天我投降了

  • 延遲
    //創(chuàng)建一個(gè)信號(hào)
    RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id subscriber) {
    NSLog(@"等等我义锥,我還有10秒鐘就到了");
    [subscriber sendNext:@"天河中心"];
    [subscriber sendCompleted];
    return nil;
    }];
    //延時(shí)10秒接受Next玻璃球
    [[signal delay:10] subscribeNext:^(NSString x) {
    NSLog(@"我到了%@",x);
    }];
    /

    [2016-04-21 13:20:10]等等我拌倍,我還有10秒鐘就到了
    [2016-04-21 13:20:20]我到了天河中心
    */

  • 超時(shí)處理
    RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id subscriber) {
    //創(chuàng)建發(fā)送信息信號(hào)
    NSLog(@"我快到了");
    RACSignal sendSignal = [RACSignal createSignal:^RACDisposable (id sendSubscriber) {
    [sendSubscriber sendNext:nil];
    [sendSubscriber sendCompleted];
    return nil;
    }];
    //發(fā)送信息要1個(gè)小時(shí)10分鐘才到
    [[sendSignal delay:60
    70] subscribeNext:^(id x) {
    //這里才發(fā)送Next玻璃球到signal
    [subscriber sendNext:@"我到了"];
    [subscriber sendCompleted];
    }];
    return nil;
    }];
    //這里對(duì)signal進(jìn)行超時(shí)接受處理
    [[signal timeout:60
    60
    onScheduler:[RACScheduler mainThreadScheduler] ]
    subscribeError:^(NSError *error)
    {
    //超時(shí)錯(cuò)誤處理
    NSLog(@"等了你一個(gè)小時(shí)了柱恤,你還沒(méi)來(lái)梗顺,我走了");
    }];

  • 重試
    __block int failedCount = 0;
    //創(chuàng)建信號(hào)
    RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id subscriber) {
    if (failedCount < 100) {
    failedCount++;
    NSLog(@"我失敗了");
    //發(fā)送錯(cuò)誤寺谤,才會(huì)要重試
    [subscriber sendError:nil];
    } else {
    NSLog(@"經(jīng)歷了數(shù)百次失敗后");
    [subscriber sendNext:nil];
    }
    return nil;
    }];
    //重試
    RACSignal *retrySignal = [signal retry];
    //直到發(fā)送了Next玻璃球
    [retrySignal subscribeNext:^(id x) {
    NSLog(@"終于成功了");
    }];

  • 節(jié)流
    RACSignal *signal = [RACSignal createSignal:^RACDisposable (id subscriber) {
    //即時(shí)發(fā)送一個(gè)Next玻璃球
    [subscriber sendNext:@"A"];
    //下面是GCD延時(shí)發(fā)送Next玻璃球
    dispatch_queue_t mainQueue = dispatch_get_main_queue();
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(int64_t)(1 * NSEC_PER_SEC)),mainQueue, ^{
    [subscriber sendNext:@"B"];
    });
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(int64_t)(2 * NSEC_PER_SEC)),mainQueue, ^{
    //發(fā)送多個(gè)Next变屁,如果節(jié)流了薄料,接收最新發(fā)送的
    [subscriber sendNext:@"C"];
    [subscriber sendNext:@"D"];
    [subscriber sendNext:@"E"];
    });
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(int64_t)(3 * NSEC_PER_SEC)),mainQueue, ^{
    [subscriber sendNext:@"F"];
    });
    return nil;
    }];
    //對(duì)信號(hào)進(jìn)行節(jié)流摄职,限制短時(shí)間內(nèi)一次只能接收一個(gè)Next玻璃球
    [[signal throttle:1] subscribeNext:^(id x) {
    NSLog(@"%@通過(guò)了",x);
    }];
    /

    A
    B
    E
    F
    *

  • 條件 (直到什么時(shí)候才 takeUntil)
    //創(chuàng)建取值信號(hào)
    RACSignal *takeSignal = [RACSignal createSignal:^RACDisposable *(id subscriber) {
    //創(chuàng)建一個(gè)定時(shí)器信號(hào)谷市,每隔1秒觸發(fā)一次
    RACSignal *signal = [RACSignal interval:1
    onScheduler:[RACScheduler mainThreadScheduler]];
    //定時(shí)接收
    [signal subscribeNext:^(id x) {

              [subscriber sendNext:@"我不玩游戲除非你求我"];
          }];
          return nil;
      }];
      //創(chuàng)建條件信號(hào)
      RACSignal *conditionSignal = [RACSignal createSignal:^RACDisposable *(id subscriber) {
          //設(shè)置5秒后發(fā)生Complete玻璃球
      
          dispatch_after(dispatch_time(DISPATCH_TIME_NOW,
                                       (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
              NSLog(@"我求你了");
              [subscriber sendCompleted];
          });
          return nil;
      }];
      //設(shè)置條件迫悠,takeSignal信號(hào)在conditionSignal信號(hào)接收完成前,不斷地取值
      [[takeSignal takeUntil:conditionSignal] subscribeNext:^(id x) {
          NSLog(@"%@", x);
      }];
      /*
      我不玩游戲除非你求我
      我不玩游戲除非你求我  
      我不玩游戲除非你求我  
      我不玩游戲除非你求我  
      我不玩游戲除非你求我 
      我求你了  
       */
    
4.常用宏
    // RAC 用于給某個(gè)對(duì)象的屬性綁定
RAC(self.sendBut.titleLabel,text) = self.textF.rac_textSignal;

//RACObserve(self, name):監(jiān)聽(tīng)某個(gè)對(duì)象的某個(gè)屬性,返回的是信號(hào)括蝠。
[RACObserve(self.view, center)subscribeNext:^(id x) {
    NSLog(@"%@",x);
}];
@weakify(self); @strongify(self);
// RACTuplePack:把數(shù)據(jù)包裝成RACTuple(元組類(lèi))
// 把參數(shù)中的數(shù)據(jù)包裝成元組
RACTuple *tuple1 = RACTuplePack(@10,@20);
 //RACTupleUnpack:把RACTuple(元組類(lèi))解包成對(duì)應(yīng)的數(shù)據(jù)忌警。
  // 把參數(shù)中的數(shù)據(jù)包裝成元組
  RACTuple *tuple = RACTuplePack(@"img",@20);
 // 解包元組法绵,會(huì)把元組的值朋譬,按順序給參數(shù)里面的變量賦值
 // name = @"xmg" age = @20
 RACTupleUnpack(NSString *name,NSNumber *age) = tuple;
5.項(xiàng)目中使用示例

網(wǎng)絡(luò)請(qǐng)求
- (RACSubject *)POST:(NSString *)path parameters:(id)parameters
{
RACReplaySubject *signal = [RACReplaySubject replaySubjectWithCapacity:1];
NSURLSessionDataTask *task = [[PR_HTTPSessionManager defaultManager] POST:path parameters:[[self class] addPublicParameters:parameters] success:^(NSURLSessionDataTask *task, id responseObject){
NSDictionary * responseDict = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:nil];

        NSError *error = [[self class] errorForResponseObject:responseDict];
        if (error) {
             [signal sendError:error];
        } else {
            id data = responseDict[@"results"];
            [signal sendNext:data];
            [signal sendCompleted];
        }
    } failure:^(NSURLSessionDataTask *task, NSError *error) {
        
        [signal sendError:[[self class] localizedError:error]];
    }];
  
@weakify(task);
RACDisposable * dispose = [RACDisposable disposableWithBlock:^{
    @strongify(task);
    [task cancel];
}];

RACCompoundDisposable * compoundDispose = [RACCompoundDisposable compoundDisposableWithDisposables:@[dispose]];
[signal didSubscribeWithDisposable:compoundDispose];

return signal;
}


  + (RACSignal *)updateUserInfo:(NSDictionary *)params {
RACSignal *signal = [RACSignal empty];
NSString *method = @"xxxxxx";
signal =
    [[PR_HTTPSessionManager defaultManager] POST:method parameters:params];
return signal;
}  

一段賦值代碼

 @weakify(self);
 RAC(self.suggestTitleLabel,text) = RACObserve(self, viewModel.title);
 [[RACObserve(self, viewModel) ignore:nil] subscribeNext:^(DoctorSuggestTableViewCellModel  *cellViewModel) {
    @strongify(self);
    [self.textField setText:cellViewModel.contentString];
    self.suggestCollectionView.allowsMultipleSelection = cellViewModel.allowsMultipleSelection;
    
    [[self.textField.rac_textSignal takeUntil:self.rac_prepareForReuseSignal] subscribeNext:^(id x) {
        @strongify(self);
        self.viewModel.contentString = x;
    }];
     [[RACObserve(self.otherTextView,content) takeUntil:self.rac_prepareForReuseSignal]subscribeNext:^(id x)       {
        @strongify(self);
        self.viewModel.descriptionString = x;
    }];

}]; 

當(dāng)然還有很多使用到的地方就不在累述 Dome地址

以上都是入門(mén)級(jí)的使用,希望可以對(duì)你有所幫助犀忱!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末阴汇,一起剝皮案震驚了整個(gè)濱河市搀庶,隨后出現(xiàn)的幾起案子哥倔,更是在濱河造成了極大的恐慌揍庄,老刑警劉巖蚂子,帶你破解...
    沈念sama閱讀 216,919評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件食茎,死亡現(xiàn)場(chǎng)離奇詭異别渔,居然都是意外死亡惧互,警方通過(guò)查閱死者的電腦和手機(jī)喊儡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,567評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)管宵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人秋度,你說(shuō)我怎么就攤上這事钱床〔榕疲” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,316評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀(guān)的道長(zhǎng)唠倦。 經(jīng)常有香客問(wèn)我稠鼻,道長(zhǎng)狂票,這世上最難降的妖魔是什么闺属? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,294評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮屋剑,結(jié)果婚禮上润匙,老公的妹妹穿的比我還像新娘。我一直安慰自己唉匾,他們只是感情好孕讳,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,318評(píng)論 6 390
  • 文/花漫 我一把揭開(kāi)白布匠楚。 她就那樣靜靜地躺著,像睡著了一般厂财。 火紅的嫁衣襯著肌膚如雪芋簿。 梳的紋絲不亂的頭發(fā)上璃饱,一...
    開(kāi)封第一講書(shū)人閱讀 51,245評(píng)論 1 299
  • 那天与斤,我揣著相機(jī)與錄音,去河邊找鬼荚恶。 笑死撩穿,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的谒撼。 我是一名探鬼主播食寡,決...
    沈念sama閱讀 40,120評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼廓潜!你這毒婦竟也來(lái)了抵皱?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,964評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤辩蛋,失蹤者是張志新(化名)和其女友劉穎呻畸,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體悼院,經(jīng)...
    沈念sama閱讀 45,376評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡伤为,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,592評(píng)論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了樱蛤。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片钮呀。...
    茶點(diǎn)故事閱讀 39,764評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖昨凡,靈堂內(nèi)的尸體忽然破棺而出爽醋,到底是詐尸還是另有隱情,我是刑警寧澤便脊,帶...
    沈念sama閱讀 35,460評(píng)論 5 344
  • 正文 年R本政府宣布蚂四,位于F島的核電站,受9級(jí)特大地震影響哪痰,放射性物質(zhì)發(fā)生泄漏遂赠。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,070評(píng)論 3 327
  • 文/蒙蒙 一晌杰、第九天 我趴在偏房一處隱蔽的房頂上張望跷睦。 院中可真熱鬧,春花似錦肋演、人聲如沸抑诸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,697評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)蜕乡。三九已至奸绷,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間层玲,已是汗流浹背号醉。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,846評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留辛块,地道東北人畔派。 一個(gè)月前我還...
    沈念sama閱讀 47,819評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像润绵,于是被迫代替她去往敵國(guó)和親父虑。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,665評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容