ReactiveCocoa 入門知識——歸總篇


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


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

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


1.創(chuàng)建信號

方法1:

   RACSubscriber:表示訂閱者的意思,用于發(fā)送信號,這是一個協(xié)議,不是一個類,只要遵守這個協(xié)議,并且實現(xiàn)方 v     法才 能成為訂閱者。通過create創(chuàng)建的信號,都有一個訂閱者,幫助他發(fā)送數(shù)據(jù)。
 RACDisposable:用于取消訂閱或者清理資源,當(dāng)信號發(fā)送完成或者發(fā)送錯誤的時候,就會自動觸發(fā)它。
RACSignal *siganl = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
    // block調(diào)用時刻:每當(dāng)有訂閱者訂閱信號,就會調(diào)用block。
    // 2.發(fā)送信號
    [subscriber sendNext:@1];
    // 如果不在發(fā)送數(shù)據(jù),發(fā)送信號完成,內(nèi)部會自動調(diào)用[RACDisposable disposable]取消訂閱信號。
    [subscriber sendCompleted];
    return [RACDisposable disposableWithBlock:^{
        // block調(diào)用時刻:當(dāng)信號發(fā)送完成或者發(fā)送錯誤,就會自動執(zhí)行這個block,取消訂閱信號。
        // 執(zhí)行完Block后,當(dāng)前信號就不在被訂閱了。
        NSLog(@"信號被銷毀");
    }];
}];
// 3.訂閱信號,才會激活信號.
[siganl subscribeNext:^(id x) {
    // block調(diào)用時刻:每當(dāng)有信號發(fā)出數(shù)據(jù),就會調(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] 信號被銷毀

方法2:

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

方法3:

  // RACReplaySubject使用步驟:
  // 1.創(chuàng)建信號 [RACSubject subject],跟RACSiganl不一樣,創(chuàng)建信號時沒有block。
  // 2.可以先訂閱信號,也可以先發(fā)送信號。
  // 2.1 訂閱信號 - (RACDisposable *)subscribeNext:(void (^)(id x))nextBlock
  // 2.2 發(fā)送信號 sendNext:(id)value
  // RACReplaySubject:底層實現(xiàn)和RACSubject不一樣。
  // 1.調(diào)用sendNext發(fā)送信號,把值保存起來,然后遍歷剛剛保存的所有訂閱者,一個一個調(diào)用訂閱者的nextBlock。
  // 2.調(diào)用subscribeNext訂閱信號,遍歷保存的所有值,一個一個調(diào)用訂閱者的nextBlock
  // 如果想當(dāng)一個信號被訂閱,就重復(fù)播放之前所有值,需要先發(fā)送信號,在訂閱信號。
  // 也就是先保存值,在訂閱值。

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

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

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

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


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

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

 2017-06-06 16:51:00.570 ReactiveCocoaDome[18117:6914095] 第一個訂閱者接收到的數(shù)據(jù)2
 2017-06-06 16:51:00.570 ReactiveCocoaDome[18117:6914095] 第二個訂閱者接收到的數(shù)據(jù)2
2.針對不同對象的基本使用方法
  • 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(@"點擊了通知按鈕 %@",x);
    }];
    [self.navigationController pushViewController:sendV animated:YES];
    }];
    觸發(fā)信號

     _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,這時命令才執(zhí)行完畢。
         [subscriber sendCompleted];
          return [RACDisposable disposableWithBlock:^{     
         }];
        }];
      }];
    
  • NSArray
    NSArray *numbers = @[@1,@2,@3,@4];
    // 這里其實是三步
    // 第一步: 把數(shù)組轉(zhuǎn)換成集合RACSequence numbers.rac_sequence
    // 第二步: 把集合RACSequence轉(zhuǎn)換RACSignal信號類,numbers.rac_sequence.signal
    // 第三步: 訂閱信號,激活信號,會自動把集合中的所有值,遍歷出來。
    [numbers.rac_sequence.signal subscribeNext:^(id x) {
    NSLog(@"數(shù)組元素 %@",x);
    }];

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

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

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

  // map:映射的意思,目的:把原始值value映射成一個新值
  // array: 把集合轉(zhuǎn)換成數(shù)組
  // 底層實現(xiàn):當(dāng)信號被訂閱,會遍歷集合中的原始值,映射成新值,并且保存到新的數(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(@"鍵盤彈出");
     }];
    
  • UITextField
    [textF.rac_textSignal subscribeNext:^(id x) {
    NSLog(@"文字改變了%@",x);
    }];

  • 定時器

    //創(chuàng)建定時器信號,定時8個小時
      RACSignal *signal = [RACSignal interval:60*60*8
                                  onScheduler:[RACScheduler mainThreadScheduler]];
      //定時執(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ā)送出去的信號";
      }]takeUntil:self.rac_willDeallocSignal];
     [singal subscribeNext:^(id x) {
      NSLog(@"x == %@",x);
     }];
    
  • 代理
    @protocol ProgrammerDelegate
    - (void)makeAnApp;
    @end

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

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

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

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

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

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

  • 過濾

    //創(chuàng)建信號
      RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id subscriber) {
          [subscriber sendNext:@(15)];
          [subscriber sendNext:@(17)];
          [subscriber sendNext:@(21)];
          [subscriber sendNext:@(14)];
          [subscriber sendNext:@(30)];
          return nil;
      }];
      //過濾信號,并打印
      [[signal filter:^BOOL(NSNumber* value) {
          //值大于等于18的才能通過過濾網(wǎng)
          return value.integerValue >= 18;
      }] subscribeNext:^(id x) {
          NSLog(@"%@", x);
      }];
      //打?。?1 30
    
  • 命令
    //創(chuàng)建命令
    RACCommand *aCommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(NSString *input) {
    //命令執(zhí)行代碼
    NSLog(@"%@我投降了",input);
    //返回一個RACSignal信號
    return [RACSignal createSignal:^RACDisposable *(id subscriber) {
    [subscriber sendCompleted];
    return nil;
    }];
    }];
    //執(zhí)行命令
    [aCommand execute:@"今天"];
    //打?。航裉煳彝督盗?/p>

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

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

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

  • 重試
    __block int failedCount = 0;
    //創(chuàng)建信號
    RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id subscriber) {
    if (failedCount < 100) {
    failedCount++;
    NSLog(@"我失敗了");
    //發(fā)送錯誤,才會要重試
    [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) {
    //即時發(fā)送一個Next玻璃球
    [subscriber sendNext:@"A"];
    //下面是GCD延時發(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ā)送多個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;
    }];
    //對信號進(jìn)行節(jié)流,限制短時間內(nèi)一次只能接收一個Next玻璃球
    [[signal throttle:1] subscribeNext:^(id x) {
    NSLog(@"%@通過了",x);
    }];
    /

    A
    B
    E
    F
    *

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

              [subscriber sendNext:@"我不玩游戲除非你求我"];
          }];
          return nil;
      }];
      //創(chuàng)建條件信號
      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信號在conditionSignal信號接收完成前,不斷地取值
      [[takeSignal takeUntil:conditionSignal] subscribeNext:^(id x) {
          NSLog(@"%@", x);
      }];
      /*
      我不玩游戲除非你求我
      我不玩游戲除非你求我  
      我不玩游戲除非你求我  
      我不玩游戲除非你求我  
      我不玩游戲除非你求我 
      我求你了  
       */
    
4.常用宏
    // RAC 用于給某個對象的屬性綁定
RAC(self.sendBut.titleLabel,text) = self.textF.rac_textSignal;

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

網(wǎng)絡(luò)請求
- (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地址

以上都是入門級的使用,希望可以對你有所幫助!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容