reactiveCocoa实践二

来源:互联网 发布:mac os 软件推荐 编辑:程序博客网 时间:2024/05/22 05:20
 .信号类:表示有数据产生

*   RACSignal

*  RACDynamicSignal -> didSubscribe(block)

*   RACSubject -> subscribers(数组)

*  RACReplaySubject -> valuesReceived(数组)


 .不同的信号订阅方式不同

*  RACDynamicSignal :
* 1.创建订阅者RACSubscriber
* 2.
执行didSubscribe

*  RACSubject :
* 1.创建订阅者RACSubscriber
* 2.
保存订阅者

*  RACReplaySubject :
* 1.创建订阅者RACSubscriber
* 2.
拿到当前创建订阅者,发送之前保存的所有值

 .订阅者:发送数据

*  RACSubscriber -> nextBlock(block)

*  RACSubject -> subscribers(数组)

*  RACReplaySubject -> valuesReceived(数组)

 .不同订阅者,发送数据方式不同

* [ RACSubscriber  sendNext]:
* 执行nextBlock

* [ RACSubject  sendNext]:
* 遍历自己所有订阅者,发送数据

* [ RACReplaySubject  sendNext]:
* 1.保存发送的值
* 2.遍历自己所有订阅者,发送数据


常用宏
- (void)RAC
{
   
// 监听文本框内容
   
//    [_textField.rac_textSignal subscribeNext:^(id x) {
   
//
   
//        _label.text = x;
   
//    }];
   
   
// 用来给某个对象的某个属性绑定信号,只要产生信号内容,就会把内容给属性赋值
    RAC(_label,text) = _textField.rac_textSignal;
}


//只要这个对象的属性一改变就会产生信号
    [RACObserve(
self.view, frame) subscribeNext:^(idx) {
        NSLog(
@"%@",x);
    }];

等同于
 [[self.viewrac_valuesForKeyPath:@"frame"observer:nil] subscribeNext:^(id x) {
      // x:修改的值  
        NSLog(@"%@",x);
    }];


 //包装元组
    RACTuple *tuple = RACTuplePack(@1,@2);
   
    NSLog(@"%@",tuple[0]); 



//弱引用(避免造成循环引用)
  @weakify(self);
   
    RACSignal *signal = [RACSignal createSignal:^RACDisposable *(
id<RACSubscriber> subscriber) {
      
        @strongify(
self)
       
        NSLog(
@"%@",self);
       
       
return nil;
    }];
    _signal = signal;




RACMulticastConnection
 每次订阅不要都请求一次,指向请求一次,每次订阅只要拿到数据
   
   
// 不管订阅多少次信号,就会请求一次
   
// RACMulticastConnection:必须要有信号
   
   
// 1.创建信号
   
// 2.把信号转换成连接类
   
// 3.订阅连接类的信号
    // 4.连接

- (void)subject
{
    RACSubject *subject = [RACSubject subject];
   
    [subject subscribeNext:^(
idx) {
       
        NSLog(
@"1:%@",x);
       
    }];
    [subject subscribeNext:^(
idx) {
       
        NSLog(
@"2:%@",x);
       
    }];
   
    [subject sendNext:
@1];
}

- (void)connect1
{
   
   
// 1.创建信号
    RACSignal *signal = [RACSignal createSignal:^RACDisposable *(
id<RACSubscriber> subscriber) {
       
// didSubscribe什么时候来:连接类连接的时候
        NSLog(
@"发送热门模块的请求");
        [subscriber sendNext:
@"热门模块的数据"];
       
       
return nil;
    }];
   
// 2.把信号转换成连接类
   
// 确定源信号的订阅者RACSubject
   
   
//先订阅再发送
   
//RACMulticastConnection *connection = [signal publish];
   
//先发送再订阅
    RACMulticastConnection *connection = [signal multicast:[RACReplaySubject subject]];
   
   
// 3.订阅连接类信号
    [connection.signal subscribeNext:^(
idx) {
       
       
// nextBlock:发送数据就会来
        NSLog(
@"订阅者1:%@",x);
       
    }];
   
   
// 4.连接
    [connection connect];

}

- (void)requestBug
{
   
// 1.创建信号
    RACSignal *signal = [RACSignal createSignal:^RACDisposable *(
id<RACSubscriber> subscriber) {
       
        NSLog(
@"发送热门模块的请求");
       
       
// 3.发送数据
        [subscriber sendNext:
@1];
       
       
return nil;
    }];
   
   
// 2.订阅信号
    [signal subscribeNext:^(
idx) {
        NSLog(
@"订阅者一%@",x);
    }];
   
    [signal subscribeNext:^(
idx) {
       
        NSLog(
@"订阅者二%@",x);
    }];

}








RACCommand
1.方式一:直接订阅执行命令返回的信号(先发送信号,再订阅)
- (void)command
{
   
// RACCommand:处理事件
   
// RACCommand:不能返回一个空的信号
   
// 1.创建命令
    RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(
idinput) {
       
// input:执行命令传入参数
       
// Block调用:执行命令的时候就会调用
        NSLog(
@"%@",input);
       
       
return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
           
           
// 发送数据
            [subscriber sendNext:
@"执行命令产生的数据"];
           
           
return nil;
        }];
    }];
   
   
// 如何拿到执行命令中产生的数据
   
// 订阅命令内部的信号
   
   
   
   
// 2.执行命令
    RACSignal *signal = [command execute:@1];
   
   
// 3.订阅信号
    [signal subscribeNext:^(
idx) {
        NSLog(
@"%@",x);
    }];

}


2.方式二:拿到正在执行的信号RACSignal,订阅正在执行的信号(先订阅,再发送信号)
- (void)executionSignals
{
   
// 1.创建命令
    RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(
idinput) {
       
// input:执行命令传入参数
       
// Block调用:执行命令的时候就会调用
        NSLog(
@"%@",input);
       
       
return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
           
           
// 发送数据
            [subscriber sendNext:
@"执行命令产生的数据"];
           
           
return nil;
        }];
    }];
   
   
// 订阅信号
   
// 注意:必须要在执行命令前,订阅
   
// executionSignals:信号源,信号中信号,signalOfSignals:信号:发送数据就是信号
   
// 拿到执行中的信号
   
//    [command.executionSignals subscribeNext:^(RACSignal *x) {
   
//
   
//        [x subscribeNext:^(id x) {
   
//            NSLog(@"%@",x);
   
//        }];
   
//
   
//    }];
   
   
// switchToLatest获取最新发送的信号,只能用于信号中信号
    [command.executionSignals.switchToLatest subscribeNext:^(
idx) {
        NSLog(
@"%@",x);
    }];
   
   
// 2.执行命令
    [command execute:@1];
}



3.switchToLatest 获取信号中信号发送的最新信号
- (void)switchToLatest
{
   
   
// 创建信号中信号
    RACSubject *signalOfSignals = [RACSubject subject];
    RACSubject *signalA = [RACSubject subject];
    RACSubject *signalB = [RACSubject subject];
   
   
// 订阅信号
   
//    [signalOfSignals subscribeNext:^(RACSignal *x) {
   
//        [x subscribeNext:^(id x) {
   
//            NSLog(@"%@",x);
   
//        }];
   
//    }];
   
// switchToLatest:获取信号中信号发送的最新信号
    [signalOfSignals.switchToLatest subscribeNext:^(
idx) {
       
        NSLog(
@"%@",x);
    }];
   
   
// 发送信号
    [signalOfSignals sendNext:signalA];
   
    [signalA sendNext:@1];
    [signalB sendNext:
@"BB"];
    [signalA sendNext:
@"11"];
}



4.监听事件有没有完成
 //当前命令内部发送数据完成,一定要主动发送完成
   
// 1.创建命令
    RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(
idinput) {
       
// input:执行命令传入参数
       
// Block调用:执行命令的时候就会调用
        NSLog(
@"%@",inpu7t);
       
       
return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
           
           
// 发送数据
            [subscriber sendNext:
@"执行命令产生的数据"];
           
           
// 发送完成
            [subscriber sendCompleted];
           
           
return nil;
        }];
    }];
   
   
// 监听事件有没有完成
    [command.executing subscribeNext:^(
idx) {
       
if ([x boolValue] ==YES) {//当前正在执行
            NSLog(
@"当前正在执行");
        }
else{
           
// 执行完成/没有执行
            NSLog(
@"执行完成/没有执行");
        }
    }];
 
   
   
// 2.执行命令
    [command execute:@1];




绑定信号(将发送的信号拦截进行一些操作)
#import"RACReturnSignal.h"
  // 1.创建信号
    RACSubject *subject = [RACSubject subject];
   
   
// 2.绑定信号
    RACSignal *bindSignal = [subject bind:^RACStreamBindBlock{
       
// block调用时刻:只要绑定信号被订阅就会调用
       
       
       
return ^RACSignal *(idvalue, BOOL *stop){
           
// block调用:只要源信号发送数据,就会调用block
           
// block作用:处理源信号内容
           
// value:源信号发送的内容
           
            NSLog(
@"接收到原信号的内容:%@",value);
           
            value = [NSString stringWithFormat:
@"xmg:%@",value];
           
// 返回信号,不能传nil,返回空信号[RACSignal empty]
           
return [RACReturnSignalreturn:value];
        };
    }];
   
   
// 3.订阅绑定信号
    [bindSignal subscribeNext:^(
idx) {
      
// blcok:当处理完信号发送数据的时候,就会调用这个Block
        NSLog(
@"接收到绑定信号处理完的信号%@",x);
    }];
   
   
// 4.发送数据
    [subject sendNext:@"123"];




映射
- (void)flattenMap
{
   
// 创建信号
    RACSubject *subject = [RACSubject subject];
   
   
// 绑定信号
    RACSignal *bindSignal = [subject flattenMap:^RACStream *(
idvalue) {
       
// block:只要源信号发送内容就会调用
       
// value:就是源信号发送内容
       
        value = [NSString stringWithFormat:
@"xmg:%@",value];
       
       
// 返回信号用来包装成修改内容值
       
return [RACReturnSignalreturn:value];
       
    }];
   
   flattenMap中返回的是什么信号,订阅的就是什么信号
   
   
// 订阅信号
    [bindSignal subscribeNext:^(
idx) {
       
        NSLog(
@"%@",x);
    }];
   
   
   
// 发送数据
    [subject sendNext:
@"123"];
}






- (void)map
{
   
// @"123"
   
// @"xmg:123"
   
   
// 创建信号
    RACSubject *subject = [RACSubject subject];
   
   
// 绑定信号
    RACSignal *bindSignal = [subject map:^id(id value) {
         map返回的类型,就是你需要映射的值
        return [NSString stringWithFormat:@"xmg:%@",value];
       
    }];
   
   
// 订阅绑定信号
    [bindSignal subscribeNext:^(
idx) {
       
        NSLog(
@"%@",x);
    }];
   
    [subject sendNext:
@"123"];
    [subject sendNext:
@"321"];
}



 

 MapflatternMap的区别:
1.FlatternMap中的Block返回信号。
2.Map中的Block返回对象。
3.开发中,如果信号发出的值不是信号,映射一般使用Map
4.开发中,如果信号发出的值是信号,映射一般使用FlatternMap



flattenMap:用于信号中信号
 
    RACSubject *signalOfsignals = [RACSubject subject];
   
    RACSubject *signal = [RACSubject subject];
   
   

//订阅信号中的信号 (3种) 方法一 :
//    [signalOfsignals subscribeNext:^(RACSignal *x) {
//       
//        [x subscribeNext:^(id x) {
//            NSLog(@"%@",x);
//        }];
//       
//    }];
    


方法二:
//    RACSignal *bindSignal = [signalOfsignals flattenMap:^RACStream *(id value) {
//        // value:源信号发送内容
//        return value;
//    }];
//   
//    [bindSignal subscribeNext:^(id x) {
//       
//        NSLog(@"%@",x);
//    }];
    [[signalOfsignals flattenMap:^RACStream *(
id value) {
       
return value;
       
    }] subscribeNext:^(
id x) {
       
        NSLog(
@"%@",x);
       
    }];
   
   
//发送信号
    [signalOfsignals sendNext:signal];
    [signal sendNext:@"213"];


方法三:switchToLatest 








0 0