ReactiveCocoa 基本使用回忆录

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/sdefzhpk/article/details/70917617

ReactiveCocoa 基本使用回忆录

RACSignal

//Signal 测试
-(void)testRacSignal{

    //1 创建信号-默认是冷信号
    RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        //3 发送数据
        NSLog(@"信号被订阅");
        [subscriber sendNext:@100];
        return nil;
    }];

    //2.订阅信号
    [signal subscribeNext:^(id x) {
        NSLog(@"信号发送的内容1 %@",x);
    }];

    [signal subscribeNext:^(id x) {
        NSLog(@"信号发送的内容2 %@",x);
    }];

}
//Signal 测试2
-(void)testRacSignal2{

    //1 创建信号-默认是冷信号
    RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        //3 发送数据
        NSLog(@"信号被订阅");
        self.subscriber = subscriber;
        [subscriber sendNext:@100];

        return [RACDisposable disposableWithBlock:^{
            //只要信号取消订阅就会来这
            NSLog(@"信号订阅完成");
        }];
    }];

    //2.订阅信号
    RACDisposable *disposable = [signal subscribeNext:^(id x) {
        NSLog(@"信号发送的内容 %@",x);
    }];
    // 1.创建订阅者,保存nextBlock
    // 2.订阅信号

    // 默认一个信号发送数据完毕们就会主动取消订阅.
    // 只要订阅者在,就不会自动取消信号订阅
    // 取消订阅信号
    [disposable dispose]; 

}

RACSubject

信号提供者,自己可以充当信号,又能发送信号

-(void)RACSubject{

    //1.创建信号
    RACSubject *subject = [RACSubject subject];

    //2.订阅信号
    [subject subscribeNext:^(id x) {
        NSLog(@"接收到数据:%@",x);
    }];

    //3.发送数据
    [subject sendNext:@100];

}

RACReplaySubject

RACReplaySubject:可以先发送信号,在订阅信号,RACSubject就不可以。

-(void)RACReplaySubject{

    RACReplaySubject *subject = [RACReplaySubject subject];


    [subject subscribeNext:^(id x) {
        NSLog(@"接收到数据:%@",x);
    }];
    [subject sendNext:@"LouKit"];

}

RACMulticastConnection

用于当一个信号,被多次订阅时,为了保证创建信号时,避免多次调用创建信号中的block,造成副作用,可以使用这个类处理

-(void)RACMulticastConnection{

    // 1.创建信号
    // 2.把信号转换成连接类
    // 3.订阅连接类的信号
    // 4.连接

    RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {

        NSLog(@"信号被订阅");
        [subscriber sendNext:@100];
        return nil;
    }];
    //把信号转换成链接类
    // 确定源信号的订阅者RACSubject
    //    RACMulticastConnection *connection = [signal publish];
    RACMulticastConnection *connection = [signal multicast:[RACReplaySubject subject]];
    //订阅信号,也不能激活信号,只是保存订阅者到数组,必须通过连接,当调用连接,就会一次性调用所有订阅者的sendNext:
    [connection.signal subscribeNext:^(id x) {
        NSLog(@"订阅者1:%@",x);
    }];
    [connection.signal subscribeNext:^(id x) {
        NSLog(@"订阅者2:%@",x);
    }];
    // 4.连接,激活信号
    [connection connect];
}

RACCommand

RAC中用于处理事件的类,可以把事件如何处理,事件中的数据如何传递,包装到这个类中,可以很方便的监控事件的执行过程。

-(void)RACCommand{
    // RACCommand:处理事件
    // RACCommand:不能返回一个空的信号

    //1.创建命令
    RACCommand *command = [[RACCommand alloc]initWithSignalBlock:^RACSignal *(id input) {
        // input:执行命令传入参数
        // Block调用:执行命令的时候就会调用
        NSLog(@"input:%@",input);

//        return[RACSignal empty];
        return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            [subscriber sendNext:@"执行命令产生的数据"];
            return nil;
        }];
    }];
    //2 执行命令

    RACSignal *signal = [command execute:@1];

    //3. 订阅信号
    [signal subscribeNext:^(id x) {

        NSLog(@"订阅到数据:%@",x);
    }];
}
-(void)RACCommand2{

    RACCommand *command = [[RACCommand alloc]initWithSignalBlock:^RACSignal *(id input) {
     return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
         [subscriber sendNext:@"data"];
         return nil;
     }];
    }];

    // 订阅信号
    // 注意:必须要在执行命令前,订阅
    //executionSignals:信号源,信号中信号,signalOfSignals:信号:发送数据就是信号
//    [command.executionSignals subscribeNext:^(RACSignal *x) {
//        [x subscribeNext:^(id x) {
//            NSLog(@"收到的数据:%@",x);
//        }];
//    }];

    // switchToLatest获取最新发送的信号,只能用于信号中信号
    [command.executionSignals.switchToLatest subscribeNext:^(id x) {
         NSLog(@"收到的数据:%@",x);
    }];
    [command execute:@1];

}
-(void)RACCommand3{
    // 当前命令内部发送数据完成,一定要主动发送完成
    // 1.创建命令
    RACCommand *command = [[RACCommand alloc]initWithSignalBlock:^RACSignal *(id input) {
        return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            [subscriber sendNext:@"data"];
            [subscriber sendCompleted];
            return nil;
        }];
    }];

    [command.executing subscribeNext:^(id x) {
        if ([x boolValue]) {
            NSLog(@"当前正在执行");// 当前正在执行
        }else{
            // 执行完成/没有执行
            NSLog(@"执行完成/没有执行");
        }
    }];

    // 2.执行命令
    [command execute:@1];

}

RACTuple、RACSequence

//RACTuple:元组类,类似NSArray,用来包装值.

//RACSequence:RAC中的集合类,用于代替NSArray,NSDictionary,可以使用它来快速遍历数组和字典。

-(void)RACTuple{

    NSArray *numbers = @[@1,@2,@3,@4];

    RACTuple *tuple = [RACTuple tupleWithObjectsFromArray:numbers];
     NSLog(@"tuple:%@",tuple[0]);

    [numbers.rac_sequence.signal subscribeNext:^(id x) {
         NSLog(@"%@",x);
    }];

    //字典
    NSDictionary *dict = @{@"key1":@"value1",@"key2":@"value2",@"key3":@100};
    [dict.rac_sequence.signal subscribeNext:^(RACTuple *tuple) {

        //       NSString *key = tuple[0];
        //        NSString *value = tuple[1];

        // RACTupleUnpack:用来解析元组
        // 宏里面的参数,传需要解析出来的变量名
        // = 右边,放需要解析的元组
        RACTupleUnpack(NSString *key,NSString *value) = tuple;
        NSLog(@"key:%@,vlaue:%@",key,value);
    }];

}

bind

    [[_textfield.rac_textSignal bind:^RACStreamBindBlock{

        return ^RACStream*(id value, BOOL *stop){

            return [RACReturnSignal return:[NSString stringWithFormat:@"LK:%@",value]];
        };
    }]subscribeNext:^(id x) {
        self.lable.text = x;

    }];

flattenMap

//映射
-(void)flattenMap{

//    flattenMap作用:把源信号的内容映射成一个新的信号,信号可以是任意类型。
    [[_textfield.rac_textSignal flattenMap:^RACStream *(id value) {
        return [RACReturnSignal return:[NSString stringWithFormat:@"LK:%@",value]];
    }]subscribeNext:^(id x) {
        self.lable.text = x;

    }];
}

map

/**
FlatternMap和Map的区别
1.FlatternMap中的Block返回信号。
2.Map中的Block返回对象。
3.开发中,如果信号发出的值不是信号,映射一般使用Map
4.开发中,如果信号发出的值是信号,映射一般使用FlatternMap。
 **/
-(void)map{

    [[_textfield.rac_textSignal map:^id(id value) {

        return [NSString stringWithFormat:@"LL:%@",value];
    }]subscribeNext:^(id x) {

        self.lable.text = x;
    }];
}

signalOfsignals

-(void)signalOfsignals{

    RACSubject *signalOfsignals = [RACSubject subject];
    RACSubject *signal = [RACSubject subject];

    [[signalOfsignals flattenMap:^RACStream *(id value) {
        //当signalOfsignals的signals发出信号才会调用
        return value;
    }]subscribeNext:^(id x) {

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

    [signalOfsignals sendNext:signal];

    [signal sendNext:@1];
}

concat

concat:按一定顺序拼接信号,当多个信号发出的时候,有顺序的接收信号。

-(void)concat{
    //concat:按一定顺序拼接信号,当多个信号发出的时候,有顺序的接收信号。
    RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {

        [subscriber sendNext:@"A100"];
        [subscriber sendCompleted];
        return nil;
    }];

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

     // 把signalA拼接到signalB后,signalA发送完成,signalB才会被激活。
    RACSignal *signal = [signalA concat:signalB];

    //注意:第一个信号必须发送完成,第二个信号才会被激活
    [signal subscribeNext:^(id x) {
        NSLog(@"%@",x);
    }];

}

then

用于连接两个信号,当第一个信号完成,才会连接then返回的信号。
注意使用then,之前信号的值会被忽略掉.

-(void)then{

    //用于连接两个信号,当第一个信号完成,才会连接then返回的信号。
    //注意使用then,之前信号的值会被忽略掉.
    [[[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        [subscriber sendNext:@100];
        [subscriber sendCompleted];
        return nil;
    }]then:^RACSignal *{
        return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            [subscriber sendNext:@200];
            [subscriber sendCompleted];
            return nil;
        }];
    }]subscribeNext:^(id x) {
        NSLog(@"%@",x);//200
    }];

}

merge

把多个信号合并为一个信号,任何一个信号有新值的时候就会调用.

-(void)merge{
    //把多个信号合并为一个信号,任何一个信号有新值的时候就会调用.
    RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {

        [subscriber sendNext:@"A100"];
        [subscriber sendCompleted];
        return nil;
    }];

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

    RACSignal *signal = [signalA merge:signalB];
    [signal subscribeNext:^(id x) {
       NSLog(@"%@",x);//200
    }];
}

zipWith

把两个信号压缩成一个信号,只有当两个信号同时发出信号内容时,并且把两个信号的内容合并成一个元组,才会触发压缩流的next事件

-(void)zipWith{
    //把两个信号压缩成一个信号,只有当两个信号同时发出信号内容时,并且把两个信号的内容合并成一个元组,才会触发压缩流的next事件
    RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {

        [subscriber sendNext:@"A100"];
        [subscriber sendCompleted];
        return nil;
    }];

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

    RACSignal *siganl = [signalA zipWith:signalB];
    [siganl subscribeNext:^(id x) {

        NSLog(@"%@",x);//包装成元组发出
        /**
         <RACTuple: 0x608000019fb0> (
        A100,
        B100
        )
         **/

    }];
}

combineLatest

将多个信号合并起来,并且拿到各个信号的最新的值,必须每个合并的signal至少都有过一次sendNext,才会触发合并的信号。

-(void)combineLatest{

    //将多个信号合并起来,并且拿到各个信号的最新的值,必须每个合并的signal至少都有过一次sendNext,才会触发合并的信号。

    RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {

        [subscriber sendNext:@"A100"];
        [subscriber sendCompleted];
        return nil;
    }];

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

    //把两个信号组合成一个信号,跟zip一样,没什么区别
    RACSignal *siganl = [signalA combineLatestWith:signalB];
    [siganl subscribeNext:^(id x) {

        NSLog(@"%@",x);//包装成元组发出
        /**
         <RACTuple: 0x608000019fb0> (
         A100,
         B100
         )
         **/

    }];
}

reduce

聚合:用于信号发出的内容是元组,把信号发出元组的值聚合成一个值

-(void)reduce{
    //聚合:用于信号发出的内容是元组,把信号发出元组的值聚合成一个值

    RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {

        [subscriber sendNext:@"A100"];
        [subscriber sendCompleted];
        return nil;
    }];

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

    // 常见的用法,(先组合在聚合)。combineLatest:(id<NSFastEnumeration>)signals reduce:(id (^)())reduceBlock
    // reduce中的block简介:
    // reduceblcok中的参数,有多少信号组合,reduceblcok就有多少参数,每个参数就是之前信号发出的内容
    // reduceblcok的返回值:聚合信号之后的内容。

    RACSignal *reduceSignal = [RACSignal combineLatest:@[signalA,signalB] reduce:^id(NSNumber *num1 ,NSNumber *num2){
        return [NSString stringWithFormat:@"%@ %@",num1,num2];
    }];

    [reduceSignal subscribeNext:^(id x) {
        NSLog(@"%@",x);
    }];

}

待续…..

猜你喜欢

转载自blog.csdn.net/sdefzhpk/article/details/70917617