美文网首页
【浓缩】一眼看透RAC(OC版:ReactiveObj)

【浓缩】一眼看透RAC(OC版:ReactiveObj)

作者: SevenJustin | 来源:发表于2016-11-15 11:51 被阅读645次

不用太多浮夸繁杂的介绍,要的就是会用。在使用中慢慢体会它带给我们开发的便利吧。你要的全在此。

//1 RACSignal
    RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        
        NSLog(@"发送请求******");
        [subscriber sendNext:@1];
        [subscriber sendCompleted];
        
        return [RACDisposable disposableWithBlock:^{
            NSLog(@"RACDisposable");
        }];
    }];
    
    [signal subscribeNext:^(id x) {
       NSLog(@"每注册一次就会发送一次请求 接收到数据1:%@",x);
    }];
    [signal subscribeNext:^(id x) {
        NSLog(@"每注册一次就会发送一次请求 接收到数据2:%@",x);
    }];

    //2 RACMulticastConnection 可防止多次执行发送请求sendNext
    RACMulticastConnection *connection = [signal publish];
    [connection.signal subscribeNext:^(id x) {
        NSLog(@"订阅者1");
    }];
    [connection.signal subscribeNext:^(id x) {
        NSLog(@"订阅者2");
    }];
    [connection connect];


    //3 RACSubject 是 RACSignal子类 sendNext会遍历所有subscriber调用其sendNext
    RACSubject *subject = [RACSubject subject];
    [subject subscribeNext:^(id x) {
        NSLog(@"RACSubject发送前第一个订阅者*****%@",x);
    }];
    [subject subscribeNext:^(id x) {
        NSLog(@"RACSubject发送前第二个订阅者*****%@",x);
    }];
    [subject sendNext:@3];
    
    //4 RACReplaySubject 是 RACSubject 子类
    RACReplaySubject *replaySubject = [RACReplaySubject subject];
    [replaySubject sendNext:@5];
    [replaySubject subscribeNext:^(id x) {
        NSLog(@"RACReplaySubject 1 发送后我才注册***%@",x);
    }];
    [replaySubject subscribeNext:^(id x) {
        NSLog(@"RACReplaySubject 2 发送后我才注册***%@",x);
    }];

    //5 RACSequence处理了队列或字典键值对(数组和字典中的元素 signal出的值:字典包装了Tuple元组 数组是值本身)
    NSArray *numbers = @[@2, @5, @8,@10];
    [numbers.rac_sequence.signal subscribeNext:^(id x) {
        NSLog(@"*****数组中的值是***%@",x);
    }];
    
    NSArray *mapNewArray = [[numbers.rac_sequence map:^id(id value) {
        return [NSString stringWithFormat:@"Map reslut value**%@",value];
    }] array];
    NSLog(@"Map出的新Array****%@", mapNewArray);
    
    NSDictionary *dictions = @{@"name":@"Bobie", @"age":@19, @"city":@"Robbin", @"number":@39};
    [dictions.rac_sequence.signal subscribeNext:^(id x) {
        RACTupleUnpack(NSString *nameValue, NSString *ageValue) = x;
        NSLog(@"***字典中的键值对是****%@****%@",nameValue,ageValue);
    }];
    
   //6 RACCommand
    _commond = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
        
        //必须要返回信号 如无则返回空信号
        // return [RACSignal empty];
        
        return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            
            [subscriber sendNext:@"发送请求"];
            [subscriber sendCompleted];
            
            return [RACDisposable disposableWithBlock:^{
                
            }];
        }];
    }];
    
    [_commond.executionSignals subscribeNext:^(id x) {
        
        NSLog(@"***subscribeNext**out***%@",x);
        
        [x subscribeNext:^(id x) {
            NSLog(@"*****subscribeNext**in**%@",x);
        }];
    }];
    [_commond.executionSignals.switchToLatest subscribeNext:^(id x) {
        NSLog(@"**switchToLatest******%@",x);
    }];
    
    [[_commond.executing skip:1] subscribeNext:^(id x) {
        if ([x boolValue] == YES) {
            NSLog(@"正在执行");
        }else{
            NSLog(@"执行完成");
        }
    }];
    
    [_commond execute:@6];
    _firstBtn.rac_command = _commond;
    
 //具体看下commond的示例:executionSignals是RACCommand的signal,每当command开始执行时next:,其参数是由command创建的signal,所以这个executionSignals是一个值为signal的signal。在command每次开始执行时得到一个包含字符串值的signal:
    RACSignal *startSignal = [_commond.executionSignals map:^id(RACSignal *value) {
        return NSLocalizedString(@"发送请求字符串", nil);
    }];
    
    //如果我们想用纯粹的函数在command执行完成后得到一个包含字符串的signal。flattenMap:方法在command执行时,会调用block并传入subscribeSignal,这个block会返回一个新的signal,它的值就在这个要返回的signal中。materialize会将一个signal转换为RACEvent信号(将一个signal的next:complete和error:消息转换为RACEvent实例的next:的值)。接下来我们就过滤这些事件,只留下RACEventTypeCompleted完成事件,并将其map成一个字符串值。
    RACSignal *completeSignal = [_commond.executionSignals flattenMap:^RACStream *(RACSignal *value) {
        
        return [[[value materialize] filter:^BOOL(RACEvent *value) {
           return value.eventType == RACEventTypeCompleted;
        }] map:^id(id value) {
            return NSLocalizedString(@"Thanks", nil);
        }];
    }];
    
    //效果等同于上面FlattenMap作用
    @weakify(self);
    [_commond.executionSignals subscribeNext:^(RACSignal*subscribeSignal) {
        
        [subscribeSignal subscribeCompleted:^{
            
            @strongify(self);
            self.myString= @"Thanks";
        }];   
    }];
    
    //executionSignals属性,这个signals不会发送了error事件,而是由errors这个属性来发送的。在一个command的执行期间,如果一个signal发送了error,这会被signals当成一个next:事件发送,而errors属性则会发送这个错误信息。errors属性不会发送error:事件。我们很容易就能将错误信息map成一个字符串消息
    RACSignal *failSignal = [[_commond.errors subscribeOn:[RACScheduler mainThreadScheduler]] map:^id(NSError *error){
        return NSLocalizedString(@"FailError", nil);
    }];
    
    //7 将这个3个signals合并成一个signal,并将其绑定到self的myString属性上
    RAC(self, myString) = [RACSignal merge:@[startSignal, completeSignal, failSignal]];
   
   //8
    @weakify(self);
    
    //监听某个方法调用 表示只要self调用btnOnclickedFirst:,就会发出信号,订阅就好了。
    [[self rac_signalForSelector:@selector(btnOnclickedFirst:)] subscribeNext:^(id x) {
        NSLog(@"**************3434343434");
    }];
    
    //监听某个属性改变为新值
    [[self rac_valuesAndChangesForKeyPath:@"mypoint" options:NSKeyValueObservingOptionNew observer:nil] subscribeNext:^(id x) {
        NSLog(@"*****mypoint 新值为***%@",x);
    }];
    
    //监听某个属性变化
    [RACObserve(self, myString) subscribeNext:^(id x) {
        NSLog(@"mystring 有变化 我知道了");
    }];
    
    //监听按钮动作
    [[_firstBtn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(id x) {
        NSLog(@"监听按钮了");
    }];
    
    
    //监听输入框输入
    [_firstTextField.rac_textSignal subscribeNext:^(id x) {
        
        @strongify(self);
        NSLog(@"文字改变了%@",x);
        NSLog(@"********改变输入框文字即改变myString**%@", self.myString);
    }];
    
    //处理多个请求,都返回结果的时候,统一做处理.当signalOne和signalTwo都至少sendNext过一次,接下来只要其中任意一个signal有了新的内容,updateMyUI:dateTwo:这个方法就会自动被触发
    RACSignal *signalOne = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        [subscriber sendNext:@"第一个请求发送"];
        return [RACDisposable disposableWithBlock:^{
        }];
    }];
    RACSignal *signalTwo = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        [subscriber sendNext:@"第二个请求发送"];
        return [RACDisposable disposableWithBlock:^{
        }];
    }];
    [self rac_liftSelector:@selector(updateMyUI:dateTwo:) withSignalsFromArray:@[signalOne, signalTwo]];
    
    //给某个对象的某个属性绑定
    RAC(self, myString) = _firstTextField.rac_textSignal;
    
    //监听通知
    [[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardWillShowNotification object:nil] subscribeNext:^(id x) {
        NSLog(@"系统通知被监听");
    }];

相关文章

网友评论

      本文标题:【浓缩】一眼看透RAC(OC版:ReactiveObj)

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