tomReactiveCocoa相关ReactiveCocoa研究

ReactiveCocoa学习篇——【下】

2015-10-20  本文已影响4340人  海强_hq

1.ReactiveCocoa开发中常见用法有哪些?

第1种:代替代理

rac_signalForSelector:用于替代代理

// 1.代替代理,RACSubject
    // RAC方法:可以判断下某个方法有没有调用
    // 只要self调用Selector就会产生一个信号
    // rac_signalForSelector:监听某个对象调用某个方法
    [[self rac_signalForSelector:@selector(didReceiveMemoryWarning)] subscribeNext:^(id x) {
        
        NSLog(@"控制器调用了didReceiveMemoryWarning");
    }];
    // 判断下redView有没有调用btnClick,就表示点击了按钮
    [[_redView rac_signalForSelector:@selector(btnClick:)] subscribeNext:^(id x) {
        NSLog(@"点击了按钮");
    }];


第2种:代替KVO

rac_valuesAndChangesForKeyPath:用于监听某个对象的属性改变

 [_redView rac_observeKeyPath:@"name" options:NSKeyValueObservingOptionNew observer:nil block:^(id value, NSDictionary *change, BOOL causedByDealloc, BOOL affectedOnlyLastComponent) {
        // 只要监听的属性一改变调用
        NSLog(@"%@",_redView.name);
    }];
    
    // KVO:第二种,只要对象的值改变,就会产生信号,订阅信号
    [[_redView rac_valuesForKeyPath:@"name" observer:nil] subscribeNext:^(id x) {
        
    }];

第3种:监听事件

rac_signalForControlEvents:用于监听某个事件

 //  只要按钮产生这个事件,就会产生一个信号
    [[_btn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(id x) {
        
        NSLog(@"按钮被点击%@",x);
    }];
    _btn.rac_command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
        NSLog(@"按钮点击");
        return [RACSignal empty];
    }];

第4种:代替通知

rac_addObserverForName:用于监听某个通知

    [[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardWillShowNotification object:nil] subscribeNext:^(id x) {
        
        NSLog(@"%@",x);
    }];

第5种:监听文本框文字改变

rac_textSignal:只要文本框发出改变就会发出这个信号

    [_textField.rac_textSignal subscribeNext:^(id x) {
        // x:文本框的文字
        NSLog(@"%@",x);
    }];

第6种:处理当界面有多次请求时,需要都获取到数据时,才能展示界面

rac_liftSelector:withSignalsFromArray:Signals:当传入的Signals(信号数组),每一个signal都至少sendNext过一次,就会去触发第一个selector参数的方法

  RACSignal *requestHot = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        NSLog(@"请求最热商品");
        [subscriber sendNext:@"获取最热商品"];
        return nil;
    }];
    
    RACSignal *requestNew = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        NSLog(@"请求最新商品");
//        [subscriber sendNext:@"获取最新商品"];
        return nil;
    }];
    
    // Selector调用:当所有信号都发送数据的时候调用
    // 数组存放信号
    // Selector注意点:参数根据数组元素决定
    // Selector方法参数类型,就是信号传递出来数据
    [self rac_liftSelector:@selector(updateUI:data2:) withSignalsFromArray:@[requestHot,requestNew]];
    
}
// 只要两个请求都请求完成的时候才会调用
- (void)updateUI:(NSString *)data1 data2:(NSString *)data2
{
    NSLog(@"%@ %@",data1,data2);
}

2.ReactiveCocoa常见宏

第一种

RAC(TARGET, [KEYPATH, [NIL_VALUE]]):用于给某个对象的某个属性绑定


    // 给某个对象的某个属性绑定一个信号,只要产生信号,就会把信号的内容给对象的属性赋值
    // 给label的text属性绑定一个信号
    RAC(_label,text) = _texfField.rac_textSignal;

第二种

RACObserve(self, name):监听某个对象的某个属性,返回的是信号

    // 观察某个对象某个属性
    [RACObserve(self, name) subscribeNext:^(id x) {
       
        NSLog(@"%@",x);
    }];

第三种

@weakify(Obj)和@strongify(Obj),一般两个都是配套使用,解决循环引用问题

第四种

RACTuplePack:把数据包装成RACTuple(元组类)

    // RACTuplePack:快速把一些数据包装成元组类
    RACTuple *tuple = RACTuplePack(@"123",@1);

第五种

RACTupleUnpack:把RACTuple(元组类)解包成对应的数据

    // 参数:需要解析生成出来变量名
    RACTupleUnpack(NSString *str,NSNumber *num) = tuple;
    
    NSLog(@"%@ %@",str,num);

3.ReactiveCocoa常见操作方法

核心方法bind的使用

  RACSignal *bindSignal = [_textField.rac_textSignal bind:^RACStreamBindBlock{
        // block调用时刻:只要一个信号被绑定就会调用.表示信号绑定完成
        
        NSLog(@"源信号被绑定");
        return ^RACStream *(id value, BOOL *stop){
            // RACStreamBindBlock什么时候调用:每次源信号发出内容,就会调用这个block
            
            // value:源信号发出的内容
            NSLog(@"源信号发出的内容:%@",value);
            
            // RACStreamBindBlock作用:在这个block处理源信号的内容
            value = [NSString stringWithFormat:@"xmg%@",value];
            // block返回值:信号(把处理完的值包装成一个信号,返回出去)
            
            // 创建一个信号,并且这个信号的传递的值是我们处理完的值,value
            return [RACReturnSignal return:value];
        };
        
    }];
    
    // 订阅绑定信号,不在是源信号
    [bindSignal subscribeNext:^(id x) {
       
        NSLog(@"%@",x);
    }];
    

    // 执行流程
    /*
        1.文字改变源信号
        2.绑定源信号,[_textField.rac_textSignal bind]
        * 调用bind返回绑定好的信号,didSubscribe
        3.订阅绑定信号
            * 创建订阅者
            * 调用绑定信号的didSubscribe
        4.执行绑定信号didSubscribe
        5.执行bind方法传入的block
        6.订阅源信号
        7.只要源信号一发出内容,就会调用id signal = bindingBlock(x, &stop);
            * signal:把值处理完的信号
        
     */

ReactiveCocoa操作方法之映射(flattenMap,Map)

flattenMap:信号中信号,signalOfSignals

[[_textField.rac_textSignal flattenMap:^RACStream *(id value) {
        // value:源信号的内容
        value = [NSString stringWithFormat:@"xmg%@",value];
        // 返回值:信号,把处理完的值包装成信号返回出去
        return [RACReturnSignal return:value];
    }] subscribeNext:^(id x) {
        // 订阅[RACReturnSignal return:value发送值
        
        // x:绑定信号的值
        NSLog(@"%@",x);
    }];

map: 用于普通信号,信号发出普通值

  [[_textField.rac_textSignal map:^id(id value) {
        // value:源信号的内容
        // 返回值,就是处理源信号的内容,直接返回
        return [NSString stringWithFormat:@"----xmg%@",value];
        
    }] subscribeNext:^(id x) {
        NSLog(@"%@",x);
    }];

FlatternMap和Map的区别

ReactiveCocoa操作方法之组合

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

 // concat:连接信号,有顺序的拼接,一定要等第一个信号完成的时候,第二个信号才会被激活
    RACSubject *signalA = [RACSubject subject];
    RACSubject *signalB = [RACSubject subject];
    
    // 组合信号
    RACSignal *signals = [signalA concat:signalB];
    
    // 订阅组合信号
    [signals subscribeNext:^(id x) {
        
        NSLog(@"%@",x);
    }];
    
    // 发送数据
    [signalA sendNext:@1];
    [signalA sendCompleted];
    [signalB sendNext:@2];

then:用于连接两个信号,当第一个信号完成,才会连接then返回的信号

 RACSubject *signalA = [RACSubject subject];
    RACSubject *signalB = [RACSubject subject];
    
    // 组合
    RACSignal *signals = [signalA then:^RACSignal *{
        return signalB;
    }];
    
    [signals subscribeNext:^(id x) {
        NSLog(@"%@",x);
    }];
    
    [signalA sendNext:@1];
    [signalA sendCompleted];
    [signalB sendNext:@2];
 then跟concat区别:监听不到第一个信号的值,共同点都是必须第一个信号完成,第二个信号才会激活

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

// merge:合并,任何一个信号只要发送值,就能订阅
    RACSubject *signalA = [RACSubject subject];
    RACSubject *signalB = [RACSubject subject];
    
    RACSignal *signals = [signalA merge:signalB];
    
    [signals subscribeNext:^(id x) {
        NSLog(@"%@",x);
    }];
    
    [signalA sendNext:@1];
    
    [signalB sendNext:@2];
    
    [signalB sendNext:@3];

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

RACSubject *signalA = [RACSubject subject];
    RACSubject *signalB = [RACSubject subject];
    
    RACSignal *signals = [signalA zipWith:signalB];
    
    [signals subscribeNext:^(id x) {
        
        NSLog(@"%@",x);
    }];
    
    // zipWith:当两个信号都发出内容的时候,才能被订阅到
    [signalA sendNext:@1];
    [signalB sendNext:@2];
    
    [signalB sendNext:@3];
    [signalA sendNext:@4];

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

  // 第一个参数:就是存放需要合并信号
    [[RACSignal combineLatest:@[_textField1.rac_textSignal,_textField2.rac_textSignal] reduce:^id(NSString *str1,NSString *str2){
        NSLog(@"%@ ---- %@",str1,str2);
        // block:只要任意一个信号发出内容,就会调用
        // block参数个数:由信号决定
        // block参数类型:block的参数就是信号发出值
        // 把两个信号中的值聚合成哪个值
        return @(str1.length && str2.length);
    }] subscribeNext:^(id x) {
        _btn.enabled = [x boolValue];
        NSLog(@"%@",x);
    }];

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

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

        [subscriber sendNext:@1];

        return nil;
    }];

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

        [subscriber sendNext:@2];

        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);
    }];

ReactiveCocoa操作方法之过滤

ReactiveCocoa操作方法之秩序

ReactiveCocoa操作方法之线程

ReactiveCocoa操作方法之时间

ReactiveCocoa操作方法之重复

4.学习MVVM架构思想

上一篇 下一篇

猜你喜欢

热点阅读