美文网首页
RACLearing (ReactiveCocoa 2.5)

RACLearing (ReactiveCocoa 2.5)

作者: 浩然爸 | 来源:发表于2018-02-08 15:12 被阅读17次
    #import "ViewController.h"
    #import "RedView.h"
    #import "NSObject+RACKVOWrapper.h"
    #import "Flag.h"
    #import "NextViewController.h"
    #import <ReactiveCocoa/ReactiveCocoa.h>
    
    @interface ViewController ()
    @property (weak, nonatomic) IBOutlet UITextField *accountLabel;
    @property (weak, nonatomic) IBOutlet UITextField *pwdLabel;
    @property (weak, nonatomic) IBOutlet UIButton *loginBtn;
    
    @property (nonatomic) id<RACSubscriber> subscriber;
    @property (weak, nonatomic) IBOutlet UITextField *txtField;
    @property (weak, nonatomic) IBOutlet UILabel *txtLabel;
    @property (weak, nonatomic) IBOutlet RedView *redView;
    @property (weak, nonatomic) IBOutlet UIButton *btn;
    
    @property (nonatomic) RACSignal *signal;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidAppear:(BOOL)animated {
        [super viewDidAppear:animated];
        
    //    NextViewController *next = [[NextViewController alloc] init];
    //    [self presentViewController:next animated:YES completion:nil];
        
    //    [self RACSequence];
        
        
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        [[@[@"you", @"are", @"beautiful"] .rac_sequence.signal map:^id(id value) {
            return [value capitalizedString];
        }] subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
        
    }
    
    //RAC常用的宏
    - (void)RACMacros {
        
        //1.RAC
    //    [_txtField.rac_textSignal subscribeNext:^(id x) {
    //        _txtLabel.text = x;
    //    }];
        //用宏更简单,用来给某个对象的属性绑定一个信号,只要产生信号内容,就会把内容给属性赋值
        RAC(_txtLabel, text) = _txtField.rac_textSignal;
        
        //2.监听某个对象的某个属性
        [RACObserve(self.view, frame) subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
        
        //3.@weakify, @strongify 防止循环引用
        @weakify(self);
        _signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            @strongify(self);
            NSLog(@"%@", self.signal);
            return nil;
        }];
        [_signal subscribeNext:^(id x) {
            
        }];
        
        
        //4.包装元组
        RACTuple *tuple = RACTuplePack(@1, @2);
        NSLog(@"%@", tuple[0]);
        
        
    }
    
    //当一个界面有多次请求的时候,需要保证所有的请求完成才能搭建界面
    - (void)lifrSelector {
        //请求第一个模块
        RACSignal *signal1 = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            //请求数据AFN
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.5f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                [subscriber sendNext:@"第一个模块"];
            });
            
            return nil;
        }];
        //请求第二个模块
        RACSignal *signal2 = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            //请求数据AFN
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                [subscriber sendNext:@"第二个模块"];
            });
            
            return nil;
        }];
        
        //数组存放信号
        //当数组中的所有信号都发送数据的时候才会执行方法
        //方法是有要求的,方法的参数必须与数组的信号一一对应
        [self rac_liftSelector:@selector(updateUI: and:) withSignalsFromArray:@[signal1, signal2]];
    }
    - (void)updateUI:(NSString *)str1 and:(NSString *)str2 {
        
        NSLog(@"两个模块加载完成--%@--%@", str1, str2);
    }
    
    - (void)RACReplace {
        //1.代替代理
        //需要传值得时候用RACSubject,不需要的时候用下面这种方法
        [[_redView rac_signalForSelector:@selector(btnClick2:)] subscribeNext:^(id x) {
            NSLog(@"红色按钮被点击了");
        }];
        
        //2.代替kvo
        [_redView rac_observeKeyPath:@"frame" options:(NSKeyValueObservingOptionNew) observer:nil block:^(id value, NSDictionary *change, BOOL causedByDealloc, BOOL affectedOnlyLastComponent) {
            
        }];
        
        [[_redView rac_valuesForKeyPath:@"frame" observer:nil] subscribeNext:^(id x) {
           //x就是修改的值;
            NSLog(@"%@", x);
        }];
        
        
        //3.监听事件
        [[_btn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(id x) {
            NSLog(@"按钮被点击了");
        }];
        
        //4.代替通知
        [[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardWillShowNotification object:nil] subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
        
        
        //5.监听文本框
        [_txtField.rac_textSignal subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
        
    }
    
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
        _redView.frame = CGRectMake(0, 0, 200, 200);
    }
    
    //NSArray NSDictionary遍历
    - (void)RACSequence {
        
        NSArray *array = @[@"111", @"222", @2];
        
        //NSArray遍历
        //数组转集合
        RACSequence *sequence = array.rac_sequence;
        //把集合转化为信号
        RACSignal *signal = sequence.signal;
        //遍历数组
        [signal subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
        
        //同上
        [array.rac_sequence.signal subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
        
        /*
        NSString *filePath = [[NSBundle mainBundle] pathForResource:@"flags.plist" ofType:nil];
        NSArray *array = [NSArray arrayWithContentsOfFile:filePath];
        NSMutableArray *mutArray = [NSMutableArray array];
        [array.rac_sequence.signal subscribeNext:^(NSDictionary *dict) {
            Flag *flag = [Flag flagWithDict:dict];
            [mutArray addObject:flag];
        }];
        
        //高级用法,代替上面
        //把集合中所有的元素映射成为一个新的对象
        NSArray *array1 = [[array.rac_sequence map:^id(NSDictionary *value) {
            
            //value 集合中的元素
            //id:返回对象就是映射的值
            return [Flag flagWithDict:value];
        }] array];
        NSLog(@"%@", array1);
        */
        
        
        
        //NSDictionary遍历
        NSDictionary *dict = @{@"account": @"name", @"name": @"xmg", @"age": @18};
        [dict.rac_sequence.signal subscribeNext:^(RACTuple *tuple) {
    //        NSString *key = tuple[0];
    //        NSString *value = tuple[1];
    //        
    //        NSLog(@"%@: %@", key, value);
            
            //或者用RAC的宏
            //参数需要穿解析出来的变量名
            RACTupleUnpack(NSString *key, NSString *value) = tuple;
            
            NSLog(@"%@: %@", key, value);
            
        } completed:^{
            NSLog(@"字典遍历完成");
        }];
        
    }
    
    //RAC集合类
    - (void)RACTuple {
        RACTuple *tuple = [RACTuple tupleWithObjectsFromArray:@[@"111", @"222", @3]];
        NSString *str = tuple[0];
        NSNumber *num = tuple[2];
        
        NSLog(@"%@", num);
    }
    
    - (void)redViewTest {
        [_redView.btnClickSignal subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
    }
    
    - (void)RACReplaySubject {
        //创建信号 RACReplaySubject 是 RACSubject子类 但是可以先发送,再订阅
        RACReplaySubject *subject = [RACReplaySubject subject];
        
        //发送信号 先保存值,然后遍历所有的订阅者去发送数据
        [subject sendNext:@"sss"];
        
        //订阅信号 遍历所有的值,然后拿到当前订阅者去发送数据
        [subject subscribeNext:^(id x) {
            NSLog(@"11---%@", x);
        }];
        [subject subscribeNext:^(id x) {
            NSLog(@"22---%@", x);
        }];
    }
    
    //RACSubject用法
    - (void)RACSubject {
        //RACSubject 信号提供者,也可以发送信号(一个发送,多个接收)
        //1.创建信号
        RACSubject *subject = [RACSubject subject];
        
        //先订阅信号,不同信号订阅的方式不一样,subject仅仅是保存订阅者到数组中
        [subject subscribeNext:^(id x) {
            NSLog(@"subject1 -- %@", x);
        }];
        [subject subscribeNext:^(id x) {
            NSLog(@"subject2 -- %@", x);
        }];
        
        //再发送信号subject从数组遍历取出所有订阅者发送数据
        [subject sendNext:@"subject"];
    }
    
    //取消订阅信号
    - (void)RACDisposable {
        //1.创建信号
        RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            //只要订阅者在,就不会自动取消订阅
            _subscriber = subscriber;
            //3.发送信号
            [subscriber sendNext:@"sss"];
            
            //默认一个信号发送数据完毕以后就会被主动取消订阅
            return [RACDisposable disposableWithBlock:^{
                //信号取消订阅就会来到这个block
                NSLog(@"信号被取消订阅");
            }];
        }];
        
        //2.订阅信号
        RACDisposable *disposable = [signal subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
        
        //主动取消订阅
        [disposable dispose];
    }
    
    //创建信号
    - (void)RACSignal {
        //    RAC使用步骤
        //1.创建信号
        RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            //didSubscribe调用,只要信号被订阅就会调用
            //didSubscribe作用:发送数据
            
            //3.发送信号
            [subscriber sendNext:@1];
            
            return nil;
        }];
        //2.订阅信号
        
        [signal subscribeNext:^(id x) {
            //nextBlock调用:只要订阅者发送数据就会调用
            //nextBlock作用:处理数据,展示到UI上
            //x 就是信号发送的内容
            
            NSLog(@"%@", x);
            
        }];
        
        //订阅者只要调用sendNext,就会执行nextBlock
        //只要信号被订阅,就会执行didSubscribe
        //前提条件是RACDynamicSignal,不同类型的订阅,处理的事情不一样
    }
    
    @end
    
    #import "NextViewController.h"
    #import <ReactiveCocoa/ReactiveCocoa.h>
    #import "NSObject+RACKVOWrapper.h"
    #import "BindViewController.h"
    
    
    @interface NextViewController ()
    
    @end
    
    @implementation NextViewController
    
    - (void)viewDidAppear:(BOOL)animated {
        [super viewDidAppear:animated];
        
        BindViewController *bind = [[BindViewController alloc] init];
        [self presentViewController:bind animated:YES completion:nil];
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view.
        self.view.backgroundColor = [UIColor groupTableViewBackgroundColor];
        
        
        
        
    //    [self RACCommand];
        
    
        
    }
    
    //switchToLatest:获取信号中的信号发送的最新的信号
    - (void)signalOfSignals {
        //高级用法
        //创建信号中的信号
        RACSubject *signalOfSignals = [RACSubject subject];
        RACSubject *subject = [RACSubject subject];
        RACSubject *subject1 = [RACSubject subject];
        //订阅信号
        [signalOfSignals subscribeNext:^(RACSignal *x) {
            [x subscribeNext:^(id x) {
                NSLog(@"%@", x);
            }];
        }];
        //switchToLatest:获取信号中的信号发送的最新的信号
        [signalOfSignals.switchToLatest subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
        
        //发送信号
        [signalOfSignals sendNext:subject];
        [subject sendNext:@"ss"];
    }
    
    //RAC中用于处理事件的类,可以把事件如何处理,事件中的数据如何传递,包装到这个类中,他可以方便的监听事件的执行过程
    - (void)RACCommand {
        //1.创建命令,
        //不能返回一个空的信号
        
        RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
            //input 就是execute传入的参数
            //block调用的时刻:只要执行命令的时候就会调用
            
            NSLog(@"%@", input);
            //不能返回nil
            return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
                
                [subscriber sendNext:@"执行命令产生的数据"];
                
                //当命令发送完成,一定要主动发送执行完成
                [subscriber sendCompleted];
                
                return nil;
            }];
            
        }];
        
        //监听事件有没有完成
        [command.executing subscribeNext:^(id x) {
            if ([x boolValue]) {
                NSLog(@"%@ 正在执行", x);
            } else {
                NSLog(@"%@ 执行完成/没有执行", x);
            }
            
        }];
        
        
        //下面的这些方法必须放在[command execute:@2]; 前面,不然不会执行
        //如何拿到执行命令中产生的数据
        //订阅命令内部的信号
        
        /*
        //1.方式一:直接订阅执行命令返回的信号
        RACSignal *signal = [command execute:@"2"];
        [signal subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
        */
        
        /*
        //2.方式二
        //不许要在执行命令前被订阅
        //订阅信号
        //executionSignals:信号源,信号中的信号。发送数据几句是信号
        [command.executionSignals subscribeNext:^(id x) {
            [x subscribeNext:^(id x) {
                NSLog(@"%@", x);
            }];
            NSLog(@"%@", x);
        }];
        
        
        //2.执行命令
        [command execute:@2];
        */
        
        //switchToLatest:获取最新发送的信号,只能用于信号中的信号
        [command.executionSignals.switchToLatest subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
        [command execute:@2];
        
        
    }
    
    // RACMulticastConnection 用于当一个信号被多次调用的时候,为了保证创建信号时,避免多次调用创建信号中的block造成副作用,可以使用这个类处理
    - (void)RACMulticastConnection {
        //每次订阅都不要都请求一次,指向请求一次,每次订阅只拿到数据
        //不管订阅多少次信号,就会请求一次
        
        //1.创建信号
        RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            
            NSLog(@"发送热门模块的请求");
            
            [subscriber sendNext:@22];
            
            return nil;
        }];
        //2.把信号转化成链接类
        RACMulticastConnection *connection = [signal publish];
    //    [signal multicast:signal]; //这个方法也可以
        
        //3.订阅链接类的信号 //NSLog(@"发送热门模块的请求") 只会发送一次,而@22会发送多次
        [connection.signal subscribeNext:^(id x) {
            NSLog(@"1.%@", x);
        }];
        
        [connection.signal subscribeNext:^(id x) {
            NSLog(@"2.%@", x);
        }];
        
        [connection.signal subscribeNext:^(id x) {
            NSLog(@"3.%@", x);
        }];
        
        //4.链接
        [connection connect];
        
    }
    
    - (void)RACSignal {
        //    RACMulticastConnection 用于当一个信号被多次调用的时候,为了保证创建信号时,避免多次调用创建信号中的block造成副作用,可以使用这个类处理
        //例如,下面这个,每次请求都会打印“发送热门模块的请求”,而有时只想要@“11”这个值
        RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            NSLog(@"发送热门模块的请求");
            [subscriber sendNext:@"11"];
            return nil;
        }];
        
        [signal subscribeNext:^(id x) {
            NSLog(@"1.%@", x);
        }];
        
        [signal subscribeNext:^(id x) {
            NSLog(@"2.%@", x);
        }];
        
        [signal subscribeNext:^(id x) {
            NSLog(@"3.%@", x);
        }];
    }
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    
    /*
    #pragma mark - Navigation
    
    // In a storyboard-based application, you will often want to do a little preparation before navigation
    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
        // Get the new view controller using [segue destinationViewController].
        // Pass the selected object to the new view controller.
    }
    */
    
    @end
    
    #import "BindViewController.h"
    #import <ReactiveCocoa/ReactiveCocoa.h>
    #import "NSObject+RACKVOWrapper.h"
    #import "CombineViewController.h"
    #import <ReactiveCocoa/RACReturnSignal.h>
    
    @interface BindViewController ()
    
    @end
    
    @implementation BindViewController
    
    - (void)viewDidAppear:(BOOL)animated {
        [super viewDidAppear:animated];
        CombineViewController *com = [[CombineViewController alloc] init];
        [self presentViewController:com animated:YES completion:nil];
        
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        self.view.backgroundColor = [UIColor whiteColor];
        // Do any additional setup after loading the view.
        
    //    [self signalOfSignals];
    }
    
    - (void)signalOfSignals {
        RACSubject *signalOfSignals = [RACSubject subject];
        RACSubject *subject = [RACSubject subject];
        
        //订阅信号
    //    [signalOfSignals subscribeNext:^(id x) {
    //        [x subscribeNext:^(id x) {
    //            NSLog(@"%@", x);
    //        }];
    //    }];
        /*
        RACSignal *bindSignal = [signalOfSignals flattenMap:^RACStream *(id value) {
            return value;
        }];
        [bindSignal subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
         */
        
        //上面的写法太麻烦,开发中用下面的写法
        [[signalOfSignals flattenMap:^RACStream *(id value) {
            return value;
        }] subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
        
        //发送信号
        [signalOfSignals sendNext:subject];
        [subject sendNext:@"12"];
    }
    
    //
    - (void)RACMap {
        //创建信号
        RACSubject *subject = [RACSubject subject];
        
        //绑定 返回任意想要的类型
        RACSignal *bindSignal = [subject map:^id(id value) {
            return @"111";
        }];
        [bindSignal subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
        
        [subject sendNext:@"aa"];
    }
    
    //一般用于信号中的信号
    - (void)RACFlattenMap {
        //创建信号
        RACSubject *subject = [RACSubject subject];
        
        //绑定 返回的RACStream *类型
        RACSignal *bindSignal = [subject flattenMap:^RACStream *(id value) {
            //value:原信号发送的内容
            //返回的信号,就是要包装的值
            return [RACReturnSignal return: [NSString stringWithFormat:@"包装的%@", value]];
        }];
        //订阅信号
        [bindSignal subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
        
        //发送数据
        [subject sendNext:@"ss"];
    }
    
    //绑定
    - (void)RACBind {
        //使用bind对原信号进行处理,然后返回
        //1.创建信号
        RACSubject *subject = [RACSubject subject];
        
        //2.hock绑定信号
        RACSignal *bindSignal = [subject bind:^RACStreamBindBlock{
            return ^RACSignal *(id value, BOOL *stop) {
                //block调用:只要原信号发送数据,就会调用block
                //value:原信号发送的内容
                NSLog(@"%@", value);
                //返回信号,不能传nil,如果想要传nil,用下面方法代替
                value = [NSString stringWithFormat:@"处理以后的信号+%@", value];
                return [RACReturnSignal return:value];
            };
        }];
        
        //3.订阅绑定信号
        [bindSignal subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
        
        //4.发送数据
        [subject sendNext:@"222"];
    }
    @end
    
    #import "CombineViewController.h"
    #import <ReactiveCocoa/ReactiveCocoa.h>
    
    @interface CombineViewController ()
    
    @end
    
    @implementation CombineViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view.
        self.view.backgroundColor = [UIColor whiteColor];
        [self skip];
    }
    
    //跳过几个信号
    - (void)skip {
        RACSubject *subject = [RACSubject subject];
        
        [[subject skip:1] subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
        
        [subject sendNext:@1];
        [subject sendNext:@2];
    }
    
    //如果当前的值跟上一次相同,就不会被订阅到
    - (void)distinctUntilChanged {
        RACSubject *subject = [RACSubject subject];
        
        [[subject distinctUntilChanged] subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
        
        [subject sendNext:@1];
        [subject sendNext:@1];
    }
    
    //获取几次信号
    - (void)take {
        RACSubject *subject = [RACSubject subject];
        RACSubject *subject1 =[RACSubject subject];
        //取前面几个值
        [[subject take:1] subscribeNext:^(id x) {
            NSLog(@"take:%@", x);
        }];
        
        //取后面几个值(必须发送 sendCompleted)
        [[subject takeLast:1] subscribeNext:^(id x) {
            NSLog(@"takeLast:%@", x);
        }];
        
        //只要传入的信号发送完成,或者发送任意数据(发送错误不行),就不会接收到原信号的内容
        [[subject takeUntil:subject1] subscribeNext:^(id x) {
            NSLog(@"takeUntil:%@", x);
        }];
        
        [subject sendNext:@"1"];//会发送
        [subject1 sendCompleted];
        [subject sendNext:@"13"];//不会发送
        [subject sendCompleted];
    }
    
    //忽略
    - (void)ignore {
        RACSubject *subject = [RACSubject subject];
        
        //忽略信号
        RACSignal *ignoreSignal = [subject ignore:@"1"];
        
        //订阅
        [ignoreSignal subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
        
        [subject sendNext:@"1"];//会被忽略
        [subject sendNext:@"13"];
    }
    
    //过滤
    - (void)filter {
        UITextField *txt1 = [[UITextField alloc] initWithFrame:CGRectMake(100, 100, 100, 40)];
        [self.view addSubview:txt1];
        
        [[txt1.rac_textSignal filter:^BOOL(id value) {
            return [value length] > 5;
        }] subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
    }
    
    //combine来组合信号
    - (void)combineAndReduce {
        UITextField *txt1 = [[UITextField alloc] initWithFrame:CGRectMake(100, 100, 100, 40)];
        [self.view addSubview:txt1];
        UITextField *txt2 = [[UITextField alloc] initWithFrame:CGRectMake(100, 150, 100, 40)];
        [self.view addSubview:txt2];
        UIButton *btn = [UIButton buttonWithType:(UIButtonTypeCustom)];
        btn.frame = CGRectMake(100, 210, 100, 40);
        btn.backgroundColor = [UIColor orangeColor];
        btn.enabled = NO;
        [self.view addSubview:btn];
        
        
        //需求:只有两个输入框都有输入的时候按钮才能点击
        //组合 combine:组合, reduce:聚合
        //reduceBlock参数:跟组合信号有关,一一对应
        RACSignal *combineSignal = [RACSignal combineLatest:@[txt1.rac_textSignal, txt2.rac_textSignal] reduce:^id(NSString *account, NSString *pwd){
            
            NSLog(@"account:%@ -- pwd:%@", account, pwd);
            //聚的值就是组合信号的内容
            //只要原信号发送内容就会调用,组合成一个系的值
            
            return @(account.length && pwd.length);
        }];
    
        //订阅
    //    [signal subscribeNext:^(id x) {
    //        btn.enabled = [x boolValue];
    //    }];
        
        //下面方法代替上面的方法
        RAC(btn, enabled) = combineSignal;
        
    }
    
    //zipWith来组合信号 :一个界面多个请求的时候,等多个秦秋完成了才能更新UI,这时候用zipWith来组合信号
    - (void)zipWith {
        //信号A
        RACSubject *signalA = [RACSubject subject];
        //信号B
        RACSubject *signalB = [RACSubject subject];
        
        //信号C
        RACSignal *signalC = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            NSLog(@"发送了C的请求");
            
            [subscriber sendNext:@"C"];
            [subscriber sendCompleted];
            return nil;
        }];
        
        //组合信号 结果与发送顺序无关,与组合顺序有关
        RACSignal *zipSignal = [[signalA zipWith:signalB] zipWith:signalC];
        [zipSignal subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
        
        [signalB sendNext:@"B"];
        [signalA sendNext:@"A"];
    }
    
    //merge 来组合信号,任意一个信号请求完成,都会被订阅到,无顺序
    - (void)merge {
        //信号A
        RACSubject *signalA = [RACSubject subject];
        //信号B
        RACSubject *signalB = [RACSubject subject];
        
        //信号C
        RACSignal *signalC = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            NSLog(@"发送了C的请求");
            
            [subscriber sendNext:@"C的数据"];
            [subscriber sendCompleted];
            return nil;
        }];
        
        //组合信号 merge
        RACSignal *mergeSignal = [[signalA merge:signalB] merge:signalC];
        
        [mergeSignal subscribeNext:^(id x) {
            //任意一个信号发送的内容都会来到这里
            NSLog(@"%@", x);
        }];
        
        
        [signalB sendNext:@"B部分"];
        [signalA sendNext:@"A部分"];
        
    }
    
    //then来组合信号
    - (void)then {
        //信号A
        RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            NSLog(@"发送了A的请求");
            
            [subscriber sendNext:@"A的数据"];
            [subscriber sendCompleted];
            return nil;
        }];
        //信号B
        RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            NSLog(@"发送了B的请求");
            
            [subscriber sendNext:@"B的数据"];
            [subscriber sendCompleted];
            return nil;
        }];
        
        //信号C
        RACSignal *signalC = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            NSLog(@"发送了C的请求");
            
            [subscriber sendNext:@"C的数据"];
            [subscriber sendCompleted];
            return nil;
        }];
        
        //组合信号 then 会忽略上面信号的值,拿到下面部分的值
        RACSignal *thenSignal = [[signalA then:^RACSignal *{
            //返回的信号就是要组合的信号
            return signalB;
        }] then:^RACSignal *{
            return signalC;
        }];
        //订阅
        [thenSignal subscribeNext:^(id x) {
            NSLog(@"%@", x);
        }];
    
    }
    
    //RAC组合信号
    - (void)concat {
        
        //信号A
        RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            NSLog(@"发送了A的请求");
            
            [subscriber sendNext:@"A的数据"];
            [subscriber sendCompleted];
            return nil;
        }];
        //信号B
        RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            NSLog(@"发送了B的请求");
            
            [subscriber sendNext:@"B的数据"];
            [subscriber sendCompleted];
            return nil;
        }];
        
        //信号C
        RACSignal *signalC = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            NSLog(@"发送了C的请求");
            
            [subscriber sendNext:@"C的数据"];
            [subscriber sendCompleted];
            return nil;
        }];
        
        //按照顺序去请求
        //创建组合信号
        RACSignal *concatSignal = [[signalA concat:signalB] concat:signalC];
        //订阅组合信号
        [concatSignal subscribeNext:^(id x) {
            //既能拿到A的信号值,又能拿到B信号的值,掐提示,每次都要发送completed
            NSLog(@"%@", x);
        }];
    }
    
    @end
    

    demo地址https://github.com/belink-QD/RACLearning

    相关文章

      网友评论

          本文标题:RACLearing (ReactiveCocoa 2.5)

          本文链接:https://www.haomeiwen.com/subject/peettftx.html