ReactiveCocoa学习总结

SherryHawki 8年前

来自: http://www.cnblogs.com/wujy/p/5177819.html

最近一直断断续续学习关于ReactiveCocoa的知识内容,对于它的一些基础内容将通过本文进行一个总结,主要是一些入门知识

一: RACSignal一些运用

@interface RACSignalTestViewController ()  @property(nonatomic,strong)RACSignal *mySignal,*secondSingl;  @end
-(RACSignal *)mySignal  {      if (!_mySignal) {          _mySignal=[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {              [subscriber sendNext:@10];              [subscriber sendCompleted];              return nil;          }];      }            return _mySignal;  }    -(RACSignal *)secondSingl  {      if (!_secondSingl) {          _secondSingl=[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {              [subscriber sendNext:@20];              [subscriber sendCompleted];              return nil;          }];      }      return _secondSingl;  }

先创建两个RACSignal的内容;将用于接下来的一些操作

//map运用 返回的值作为next的参数      [[self.mySignal map:^id(NSNumber *value) {          return [value integerValue]>5?@"踏浪帅":@"有点小";      }] subscribeNext:^(NSString *str) {          NSLog(@"map处理完成的值为:%@",str);      }];            //filter:过滤信号,使用它可以获取满足条件的信号.      [[self.mySignal filter:^BOOL(NSNumber *item) {          return [item integerValue]>5;      }] subscribeNext:^(NSNumber *x) {          NSLog(@"filter当前的值%ld",[x integerValue]);      }];                  //ignore:忽略完某些值的信号.当答合被ignore的值时就不会执行next      [[self.mySignal ignore:@10] subscribeNext:^(id x) {          NSLog(@"ignore当前的值:%@",x);      }];            //distinctUntilChanged:当上一次的值和当前的值有明显的变化就会发出信号,否则会被忽略掉。      [[self.mySignal distinctUntilChanged] subscribeNext:^(id x) {          NSLog(@"distinctUntilChanged当前的值:%@",x);      }];            //take:从开始一共取N次的信号      //takeLast:取最后N次的信号,前提条件,订阅者必须调用完成,因为只有完成,就知道总共有多少信号.      //takeUntil:(RACSignal *):获取信号直到某个信号执行完成      //skip:(NSUInteger):跳过几个信号,不接受。

运行结果:

MobileProject[885:18784] map处理完成的值为:踏浪帅  2016-02-02 16:03:07.643 MobileProject[885:18784] filter当前的值10  2016-02-02 16:03:07.644 MobileProject[885:18784] distinctUntilChanged当前的值:10

1.2:一些组合的操作

//concat:按一定顺序拼接信号,当多个信号发出的时候,有顺序的接收信号      RACSignal *concatSignal=[self.mySignal concat:self.secondSingl];      [concatSignal subscribeNext:^(id x) {          NSLog(@"concat拼接的值:%@",x);      }];              //then:用于连接两个信号,当第一个信号完成,才会连接then返回的信号      [[self.mySignal then:^RACSignal *{          @strongify(self);          return self.secondSingl;      }] subscribeNext:^(id x) {          //// 只能接收到第二个信号的值,也就是then返回信号的值          NSLog(@"then当前的值为:%@",x);      }];                  //merge:把多个信号合并为一个信号,任何一个信号有新值的时候就会调用      RACSignal *mergeSignal=[self.mySignal merge:self.secondSingl];      [mergeSignal subscribeNext:^(id x) {          NSLog(@"merge当前的值为:%@",x);      }];                  //combineLatest:将多个信号合并起来,并且拿到各个信号的最新的值,必须每个合并的signal至少都有过一次sendNext,两个信号的内容合并成一个元组RACTuple,才会触发合并的信号。      RACSignal *combineLatestSignal=[self.mySignal combineLatestWith:self.secondSingl];      [combineLatestSignal subscribeNext:^(id x) {          NSLog(@"combineLastest当前的值为:%@",x);      }];                  //zipWith:把两个信号压缩成一个信号,只有当两个信号同时发出信号内容时,并且把两个信号的内容合并成一个元组RACTuple,才会触发压缩流的next事件。      RACSignal *zipWithSignal=[self.mySignal zipWith:self.secondSingl];      [zipWithSignal subscribeNext:^(RACTuple *tuple) {          NSLog(@"zipWith当前的值为:%@",tuple);                    NSLog(@"zipWith中的RACTuple共有几个值:%ld",tuple.count);                    NSLog(@"zipWith中的RACTuple第一个值为:%@",tuple.first);                    NSLog(@"zipWith中的RACTuple最后一个值为:%@",tuple.last);      }];                  //reduce聚合:用于信号发出的内容是元组,把信号发出元组的值聚合成一个值 特别是combineLatestWith,zipWith这种返回元组的RACTuple,reduceblcok中的参数,有多少信号组合,reduceblcok就有多少参数,每个参数就是之前信号发出的内容      RACSignal *reduceSignal=[RACSignal combineLatest:@[self.mySignal,self.secondSingl] reduce:^id(NSNumber *num1 ,NSNumber *num2){          NSLog(@"combineLastest结合reduct的第一个值为:%ld 第二个值为:%ld",[num1 integerValue],[num2 integerValue]);          return ([num1 integerValue]>10&&[num2 integerValue]>15)?@"两个都符合要求":@"都没有答合要求";      }];      [reduceSignal subscribeNext:^(id x) {          NSLog(@"reduce当前的值为:%@",x);      }];

运行结果:

MobileProject[885:18784] concat拼接的值:10  2016-02-02 16:03:07.645 MobileProject[885:18784] concat拼接的值:20  2016-02-02 16:03:07.646 MobileProject[885:18784] then当前的值为:20  2016-02-02 16:03:07.646 MobileProject[885:18784] merge当前的值为:10  2016-02-02 16:03:07.646 MobileProject[885:18784] merge当前的值为:20  2016-02-02 16:03:07.647 MobileProject[885:18784] combineLastest当前的值为:<RACTuple: 0x7ff5ca606860> (      10,      20  )  2016-02-02 16:03:07.648 MobileProject[885:18784] zipWith当前的值为:<RACTuple: 0x7ff5ca60ab80> (      10,      20  )  2016-02-02 16:03:07.648 MobileProject[885:18784] zipWith中的RACTuple共有几个值:2  2016-02-02 16:03:07.648 MobileProject[885:18784] zipWith中的RACTuple第一个值为:10  2016-02-02 16:03:07.648 MobileProject[885:18784] zipWith中的RACTuple最后一个值为:20  2016-02-02 16:03:07.649 MobileProject[885:18784] combineLastest结合reduct的第一个值为:10 第二个值为:20  2016-02-02 16:03:07.720 MobileProject[885:18784] reduce当前的值为:都没有答合要求

1.3:其它一些操作:

//doNext: 执行Next之前,会先执行这个Block,可以做一些初使化的功能,doCompleted: 执行sendCompleted之前,会先执行这个Block      [[[self.mySignal doNext:^(id x) {          NSLog(@"doNext当前的值:%@",x);      }] doCompleted:^{          NSLog(@"doComplete 执行到了");      }] subscribeNext:^(id x) {          NSLog(@"测试doNext,doComplete的值:%@",x);      }];            //switchToLatest:用于signalOfSignals(信号的信号),有时候信号也会发出信号,会在signalOfSignals中,获取signalOfSignals发送的最新信号。      RACSubject *signalOfSignals = [RACSubject subject];      RACSubject *signal = [RACSubject subject];            // 获取信号中信号最近发出信号,订阅最近发出的信号。      // 注意switchToLatest:只能用于信号中的信号      [signalOfSignals.switchToLatest subscribeNext:^(id x) {                    NSLog(@"switchToLatest%@",x);      }];      [signalOfSignals sendNext:signal];      [signal sendNext:@1];            //deliverOn: 内容传递切换到制定线程中,副作用在原来线程中,把在创建信号时block中的代码称之为副作用。      //subscribeOn: 内容传递和副作用都会切换到制定线程中。'                  //timeout:超时,可以让一个信号在一定的时间后,自动报错。      [[self.mySignal timeout:1 onScheduler:[RACScheduler currentScheduler]]       subscribeNext:^(id x) {           NSLog(@"timeout当前的值:%@",x);       } error:^(NSError *error) {           NSLog(@"timeout 超时了");       }];                  //delay 延迟发送next。      [[self.mySignal delay:2] subscribeNext:^(id x) {          NSLog(@"delay执行%@",x);      }];                  //retry重试 :只要失败,就会重新执行创建信号中的block,直到成功.      __block int i = 0;      [[[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {                    if (i == 10) {              [subscriber sendNext:@100];          }else{              NSLog(@"接收到错误");              [subscriber sendError:nil];          }          i++;                    return nil;                }] retry] subscribeNext:^(id x) {                    NSLog(@"retry当前的值:%@",x);                } error:^(NSError *error) {                }];                  //普通执行多次订阅      RACSignal *oneSignal = [[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {          [subscriber sendNext:@1];          [subscriber sendNext:@2];          return nil;      }] replay];      [oneSignal subscribeNext:^(id x) {          NSLog(@"第一个没有replay执行的内容:%@",x);      }];      [oneSignal subscribeNext:^(id x) {          NSLog(@"第二个没有replay执行的内容:%@",x);      }];                  //replay重放:当一个信号被多次订阅,反复播放内容      RACSignal *replaySignal = [[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {          [subscriber sendNext:@1];          [subscriber sendNext:@2];          return nil;      }] replay];            [replaySignal subscribeNext:^(id x) {          NSLog(@"replay第一个订阅者%@",x);      }];            [replaySignal subscribeNext:^(id x) {          NSLog(@"replay第二个订阅者%@",x);      }];                  //interval 定时:每隔一段时间发出信号      [[RACSignal interval:1 onScheduler:[RACScheduler currentScheduler]] subscribeNext:^(id x) {          NSLog(@"interval一直在执行:%@",x);      }];            //throttle节流:当某个信号发送比较频繁时,可以使用节流,在某一段时间不发送信号内容,过了一段时间获取信号的最新内容发出。

运行结果:

2016-02-02 16:03:07.720 MobileProject[885:18784] doNext当前的值:10  2016-02-02 16:03:07.720 MobileProject[885:18784] 测试doNext,doComplete的值:10  2016-02-02 16:03:07.721 MobileProject[885:18784] doComplete 执行到了  2016-02-02 16:03:07.721 MobileProject[885:18784] switchToLatest1  2016-02-02 16:03:07.722 MobileProject[885:18784] timeout当前的值:10  2016-02-02 16:03:07.722 MobileProject[885:18784] 接收到错误  2016-02-02 16:03:07.723 MobileProject[885:18784] 第一个没有replay执行的内容:1  2016-02-02 16:03:07.723 MobileProject[885:18784] 第一个没有replay执行的内容:2  2016-02-02 16:03:07.723 MobileProject[885:18784] 第二个没有replay执行的内容:1  2016-02-02 16:03:07.723 MobileProject[885:18784] 第二个没有replay执行的内容:2  2016-02-02 16:03:07.724 MobileProject[885:18784] replay第一个订阅者1  2016-02-02 16:03:07.724 MobileProject[885:18784] replay第一个订阅者2  2016-02-02 16:03:07.724 MobileProject[885:18784] replay第二个订阅者1  2016-02-02 16:03:07.724 MobileProject[885:18784] replay第二个订阅者2  2016-02-02 16:03:07.838 MobileProject[885:18784] 接收到错误  2016-02-02 16:03:07.838 MobileProject[885:18784] 接收到错误  2016-02-02 16:03:07.838 MobileProject[885:18784] 接收到错误  2016-02-02 16:03:07.838 MobileProject[885:18784] 接收到错误  2016-02-02 16:03:07.839 MobileProject[885:18784] 接收到错误  2016-02-02 16:03:07.865 MobileProject[885:18784] 接收到错误  2016-02-02 16:03:07.865 MobileProject[885:18784] 接收到错误  2016-02-02 16:03:07.865 MobileProject[885:18784] 接收到错误  2016-02-02 16:03:07.866 MobileProject[885:18784] 接收到错误  2016-02-02 16:03:07.866 MobileProject[885:18784] retry当前的值:100  2016-02-02 16:03:08.726 MobileProject[885:18784] interval一直在执行:2016-02-02 08:03:08 +0000  2016-02-02 16:03:09.724 MobileProject[885:18784] delay执行10  2016-02-02 16:03:09.725 MobileProject[885:18784] interval一直在执行:2016-02-02 08:03:09 +0000  2016-02-02 16:03:10.726 MobileProject[885:18784] interval一直在执行:2016-02-02 08:03:10 +0000  2016-02-02 16:03:11.724 MobileProject[885:18784] interval一直在执行:2016-02-02 08:03:11 +0000  2016-02-02 16:03:12.727 MobileProject[885:18784] interval一直在执行:2016-02-02 08:03:12 +0000  2016-02-02 16:03:13.725 MobileProject[885:18784] interval一直在执行:2016-02-02 08:03:13 +0000  2016-02-02 16:03:14.730 MobileProject[885:18784] interval一直在执行:2016-02-02 08:03:14 +0000  2016-02-02 16:03:15.726 MobileProject[885:18784] interval一直在执行:2016-02-02 08:03:15 +0000

二:关于 RACCommand的一些知识

@interface TestRacViewController ()  @property(nonatomic,strong)UITextField *userNameText;  @property(strong,nonatomic)NSString *username;  @property(nonatomic,strong)UIButton *loginButton,*racCommendButton,*errCommendButton,*mainThreadButton,*netWorkButton,*testButton;    @property(nonatomic,strong)RACCommand *otherMyRaccomand,*mainThreadCommend,*netWorkCommend,*testPropertyCommend;  @end
//布局  -(void)loadPage  {      if (!self.userNameText) {          self.userNameText=[[UITextField alloc]init];          self.userNameText.backgroundColor=[UIColor whiteColor];          self.userNameText.placeholder=@"输入用户名";          [self.view addSubview:self.userNameText];          [self.userNameText mas_makeConstraints:^(MASConstraintMaker *make) {              make.left.mas_equalTo(self.view.mas_left).with.offset(15);              make.top.mas_equalTo(self.view.mas_top).with.offset(70);              make.right.mas_equalTo(self.view.mas_right).with.offset(-15);              make.height.mas_equalTo(@40);          }];      }            if(!self.loginButton)      {          self.loginButton=[[UIButton alloc]init];          [self.loginButton setTitle:@"响应" forState:UIControlStateNormal];          self.loginButton.backgroundColor=[UIColor blueColor];          [self.view addSubview:self.loginButton];          [self.loginButton mas_makeConstraints:^(MASConstraintMaker *make) {              make.left.mas_equalTo(self.view.mas_left).with.offset(15);              make.top.mas_equalTo(self.userNameText.mas_bottom).with.offset(20);              make.right.mas_equalTo(self.view.mas_right).with.offset(-15);              make.height.mas_equalTo(@40);          }];      }            if(!self.racCommendButton)      {          self.racCommendButton=[[UIButton alloc]init];          [self.racCommendButton setTitle:@"RacCommend测试" forState:UIControlStateNormal];          self.racCommendButton.backgroundColor=[UIColor blueColor];          [self.view addSubview:self.racCommendButton];          [self.racCommendButton mas_makeConstraints:^(MASConstraintMaker *make) {              make.left.mas_equalTo(self.view.mas_left).with.offset(15);              make.top.mas_equalTo(self.loginButton.mas_bottom).with.offset(20);              make.right.mas_equalTo(self.view.mas_right).with.offset(-15);              make.height.mas_equalTo(@40);          }];      }            if(!self.errCommendButton)      {          self.errCommendButton=[[UIButton alloc]init];          [self.errCommendButton setTitle:@"ERROR测试" forState:UIControlStateNormal];          self.errCommendButton.backgroundColor=[UIColor blueColor];          [self.view addSubview:self.errCommendButton];          [self.errCommendButton mas_makeConstraints:^(MASConstraintMaker *make) {              make.left.mas_equalTo(self.view.mas_left).with.offset(15);              make.top.mas_equalTo(self.racCommendButton.mas_bottom).with.offset(20);              make.right.mas_equalTo(self.view.mas_right).with.offset(-15);              make.height.mas_equalTo(@40);          }];      }            if(!self.mainThreadButton)      {          self.mainThreadButton=[[UIButton alloc]init];          [self.mainThreadButton setTitle:@"主线程上运行" forState:UIControlStateNormal];          self.mainThreadButton.backgroundColor=[UIColor blueColor];          [self.view addSubview:self.mainThreadButton];          [self.mainThreadButton mas_makeConstraints:^(MASConstraintMaker *make) {              make.left.mas_equalTo(self.view.mas_left).with.offset(15);              make.top.mas_equalTo(self.errCommendButton.mas_bottom).with.offset(20);              make.right.mas_equalTo(self.view.mas_right).with.offset(-15);              make.height.mas_equalTo(@40);          }];      }            if(!self.netWorkButton)      {          self.netWorkButton=[[UIButton alloc]init];          [self.netWorkButton setTitle:@"属性测试" forState:UIControlStateNormal];          self.netWorkButton.backgroundColor=[UIColor blueColor];          [self.view addSubview:self.netWorkButton];          [self.netWorkButton mas_makeConstraints:^(MASConstraintMaker *make) {              make.left.mas_equalTo(self.view.mas_left).with.offset(15);              make.top.mas_equalTo(self.mainThreadButton.mas_bottom).with.offset(20);              make.right.mas_equalTo(self.view.mas_right).with.offset(-15);              make.height.mas_equalTo(@40);          }];      }            if(!self.testButton)      {          self.testButton=[[UIButton alloc]init];          [self.testButton setTitle:@"测试特性" forState:UIControlStateNormal];          self.testButton.backgroundColor=[UIColor blueColor];          [self.view addSubview:self.testButton];          [self.testButton mas_makeConstraints:^(MASConstraintMaker *make) {              make.left.mas_equalTo(self.view.mas_left).with.offset(15);              make.top.mas_equalTo(self.netWorkButton.mas_bottom).with.offset(20);              make.right.mas_equalTo(self.view.mas_right).with.offset(-15);              make.height.mas_equalTo(@40);          }];      }  }

一些定义

//创建一个信号代码  -(RACSignal *)testSignal  {      RACSignal *signal = [RACSignal createSignal:^ RACDisposable * (id<RACSubscriber> subscriber) {          NSLog(@"创建信号");          [subscriber sendNext:@"Hi 我是一个信号"];          [subscriber sendCompleted];          return nil;      }];      return signal;  }    //创建一个命令响应  -(RACCommand *)testCommend  {      @weakify(self);      RACCommand *myCommend=[[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {          RACSignal *authSignal=[RACSignal empty];          @strongify(self);                          authSignal=[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {                        //可以根据要求加条件进行判断是否创建信号                        if ([self.username isEqualToString:@"wjy"]) {                        NSLog(@"符合要求");                        [subscriber sendNext:@"我完成的命令响应"];                        [subscriber sendCompleted];                        }                        else                        {                            //错误                            [subscriber sendError:[NSError errorWithDomain:@"报错了" code:1 userInfo:nil]];                        }                    return nil;              }];          //materialize是为了处理拿不到error的问题          return [authSignal materialize];      }];            return myCommend;  }    //创建属性的RACCommand  -(RACCommand *)otherMyRaccomand  {      if (!_otherMyRaccomand) {          _otherMyRaccomand=[[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {              NSLog(@"执行到新的RACCommand");              RACSignal *otherSignal=[RACSignal empty];              otherSignal=[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {                  if ([self.username isEqualToString:@"wjy"]) {                      [subscriber sendNext:@"我肯定可以运行的"];                      [subscriber sendCompleted];                  }                  else                  {                      [subscriber sendError:[NSError errorWithDomain:@"报错了" code:401 userInfo:nil]];                  }                  return nil;              }];              return otherSignal;          }];      }      return _otherMyRaccomand;  }      //创建主线程上运行  -(RACCommand *)mainThreadCommend  {      @weakify(self);      if (!_mainThreadCommend) {      _mainThreadCommend=[[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {          RACSignal *authSignal=[RACSignal empty];          @strongify(self);                    authSignal=[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {              @strongify(self);              //可以根据要求加条件进行判断是否创建信号              if ([self.username isEqualToString:@"wjy"]) {                  [subscriber sendNext:@(YES)];                  [subscriber sendCompleted];              }              else              {                  //错误                  [subscriber sendError:[NSError errorWithDomain:@"报错了" code:1 userInfo:nil]];              }              return nil;          }];          return authSignal;      }];      }      return _mainThreadCommend;  }      //特性测试  -(RACCommand *)testPropertyCommend  {      if (!_testPropertyCommend) {                }            return _testPropertyCommend;  }    -(RACSignal *)nettestSignal  {      RACSignal *authSignal=[RACSignal empty];            authSignal=[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {          LogInApi *reg = [[LogInApi alloc] initWithUsername:self.username password:@"123456"];          [reg startWithCompletionBlockWithSuccess:^(YTKBaseRequest *request) {              LoginModel *model=[[LoginModel alloc]initWithString:request.responseString error:nil];              [subscriber sendNext:model];              [subscriber sendCompleted];          } failure:^(YTKBaseRequest *request) {              [subscriber sendError:[NSError errorWithDomain:@"报错了" code:1 userInfo:nil]];          }];          return nil;      }];      return authSignal;  }    -(RACSignal *)netSignal  {      RACSignal *authSignal=[RACSignal empty];      authSignal=[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {          [subscriber sendNext:@"测试"];          [subscriber sendCompleted];            return nil;      }];      return authSignal;  }    //RACSubject的运用  -(RACSubject *)testSubject  {      RACSubject *sub=[RACSubject subject];      [sub sendNext:@"我是RACSubject"];      return sub;  }

运用的内容:

[self loadPage];        @weakify(self);            //把左边的属性跟右边信号signal的sendNext值绑定  distinctUntilChanged为了当值相同时不执行      RAC(self,username)=[self.userNameText.rac_textSignal distinctUntilChanged];            //监听username是否有变化,有变化就会执行subscribeNext 这个属性要支持KVO  可变数组就不可以      [RACObserve(self, username) subscribeNext:^(NSString *x) {          NSLog(@"你当前输入的值为:%@",x);      }];            //UIAlertView跟RAC结合      UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"" message:@"Alert" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];      [[alertView rac_buttonClickedSignal] subscribeNext:^(NSNumber *indexNumber) {          if ([indexNumber intValue] == 1) {              NSLog(@"你点了确定");          } else {              NSLog(@"你点了取消");          }      }];      [alertView show];            //Button响应事件      [[self.loginButton        rac_signalForControlEvents:UIControlEventTouchUpInside]          subscribeNext:^(UIButton *x) {           @strongify(self);           [[self testSignal] subscribeNext:^(id x) {               NSLog(@"当前执行值为:%@",x);           }];       }];                        //Button用命令式运行 switchToLatest处理信号中传递的参数为信号      self.racCommendButton.rac_command=[self testCommend];            //这个绑定要放在executionSignals执行前面 否则只会有一个执行完成会响应      [self.racCommendButton.rac_command.executing subscribeNext:^(id x) {          if ([x boolValue]) {              NSLog(@"rac_command正在执行中");          }          else          {              NSLog(@"rac_command执行完成");          }      }];            //dematerialize处理可以响应处理跟完成的内容      [self.racCommendButton.rac_command.executionSignals subscribeNext:^(RACSignal *execution) {          [[[execution dematerialize] deliverOn:[RACScheduler mainThreadScheduler]] subscribeNext:^(id x) {              NSLog(@"提示内容:%@",x);          } error:^(NSError *error) {               NSLog(@"racCommend出错了");          }];      }];                  //关于otherMyRaccomand的方式      self.errCommendButton.rac_command=self.otherMyRaccomand;            [self.otherMyRaccomand.executionSignals.switchToLatest subscribeNext:^(id x) {          NSLog(@"完成了 %@",x);      }];            //这边要注意是在errors 里面执行subscribeNext   不是执行subscribeError      [self.otherMyRaccomand.errors subscribeNext:^(NSError *error) {          NSLog(@"出错了 %@",error);      }];                  //主线程上操作      self.mainThreadButton.rac_command=self.mainThreadCommend;      [[[self.mainThreadCommend.executionSignals.switchToLatest map:^id(id value) {          if ([value boolValue]) {              return @"跳浪帅";          }          else          {              return @"出太阳好么";          }      }] deliverOn:[RACScheduler mainThreadScheduler]] subscribeNext:^(NSString *str) {          UIAlertView *alert=[[UIAlertView alloc]initWithTitle:@"我是弹出窗" message:[NSString stringWithFormat:@"%@",str] delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];          [alert show];      }];            //网络请求      //Button响应事件      [[self.netWorkButton        rac_signalForControlEvents:UIControlEventTouchUpInside]       subscribeNext:^(id x) {           [[[self netSignal] flattenMap:^RACStream *(id value) {                return [RACReturnSignal return:[NSString stringWithFormat:@"%@ 我已经被改变了成为另外一个信号",value]];           }]           subscribeNext:^(id x) {               NSLog(@"输出的内容:%@",x);           }];                  }];

因为代码中已经有相应的注解,所以文字说明就比较少,若有不明白可以留言;