ReactCocoa使用

通过Cocoapods集成pod ‘ReactiveObjC’

然后在项目中导入 #import <ReactiveObjC/ReactiveObjC.h>

创建RACSignal 对象,并且发送消息

@weakify(self)
    RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {

        @strongify(self)

        self.data = [[Model alloc] init];

        self.data.nameStr = @"测试完成";

        [subscriber sendNext:self.data];

        [subscriber sendCompleted];
         return nil;
    }];
     [signal subscribeNext:^(id  _Nullable x)
    {
        
        
        NSLog(@"x==========%@\n",x);
    }];
    下面是另外一种写法
    RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        
        [subscriber sendNext:@"1"];
        
        return [RACDisposable disposableWithBlock:^{
            
        }];;
    }];
    
    
    [signal subscribeNext:^(id  _Nullable x) {
       NSLog(@"结果是========%@",x);
    }];

将上面的RAC转换成flatten

  RACSignal *flattenMapSignal = [signal flattenMap:^__kindof RACSignal * _Nullable(id  _Nullable value) {

        return RACObserve(self.data, nameStr);
    }];

    [flattenMapSignal subscribeNext:^(id  _Nullable x) {


        NSLog(@"结果是=========%@\n",x);
    }];

创建RACSubject对象,执行完之后,就会执行rac_willDeallocSignal 方法

RACSubject *subject = [RACSubject subject]; 
 [subject.rac_willDeallocSignal subscribeCompleted:^{

    }];
     [subject subscribeNext:^(id x) { //3
        NSLog(@"next = %@", x);
    }];
     [subject sendNext:@1];

UITextField绑定textSignal 输出结果

   
    [[_textField.rac_textSignal bind:^RACSignalBindBlock _Nullable{
        return ^RACSignal *(id value,BOOL *stop){
            return [RACReturnSignal return:[NSString stringWithFormat:@"输出:%@",value]];
        };
    }]subscribeNext:^(id  _Nullable x) {
        NSLog(@"结果是=====%@\n",x);
    }] ;

RACReplaySubject 传的信号会重复播放

// 1.创建信号
 //1.创建信号
    RACReplaySubject *replaySubject = [RACReplaySubject subject];
    //2.发送信号
    [replaySubject sendNext:@1];
    [replaySubject sendNext:@2];
    //3.订阅信号
    [replaySubject subscribeNext:^(id x) {
        NSLog(@"第一个订阅者接收到的数据%@",x);
    }];
    //订阅信号
    [replaySubject subscribeNext:^(id x) {
        NSLog(@"第二个订阅者接收到的数据%@",x);
    }];

retry 当信号出错的时候 重新执行信号操作

    __block int i = 0;
    [[[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        if(i==10)
        {
            [subscriber sendNext:@1];
        }else{
            NSLog(@"接收到错误");
            [subscriber sendError:nil];
        }
        i++;
        return nil;
     }] retry] subscribeNext:^(id x) {
        NSLog(@"retry%@",x);
     } error:^(NSError *error) {
     }];

delay 延迟2s执行

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

        [subscriber sendNext:@1];
        
        return nil;
    
    }] delay:2] subscribeNext:^(id x) {
         NSLog(@"%@",x);
    
    }];

RACScheduler 定时做任务,当离开当前页面取消任务

   self.disposable = [[[RACSignal interval:1 onScheduler:[RACScheduler currentScheduler]] takeUntil:self.rac_willDeallocSignal] subscribeNext:^(NSDate * _Nullable x) {
         NSLog(@"做完这件事");
         [self.disposable dispose];
      }];

timeout 可以让信号在一定的时间后,自动报错

    RACSignal *signal = [[RACSignal createSignal:^RACDisposable *         _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        return  nil;
     }]timeout:1 onScheduler:[RACScheduler currentScheduler]];
    [signal subscribeNext:^(id  _Nullable x) {
        NSLog(@"====%@\n",x);
    } error:^(NSError * _Nullable error) {
        //1秒后会自动调用
        NSLog(@"%@",error);
    }];

观察某个对象的某个值的变化,并进行过滤

[[RACObserve(self,self.data) filter:^BOOL(id  _Nullable value) {
        return value;
    }] subscribeNext:^(Model *x) {
        NSLog(@"执行了这里=======%@\n",x.nameStr);
    }];

NSNotificationCenter 之观察

 [[[NSNotificationCenter defaultCenter] rac_addObserverForName:@"postData" object:nil] subscribeNext:^(NSNotification * _Nullable x) {
        NSLog(@"结果是-------%@\n",x.userInfo);
    }];
    监听按钮的事件
     UIButton *button  =[[UIButton alloc]initWithFrame:CGRectMake(50, 100, 30, 30)];
    button.backgroundColor =[UIColor redColor];
    [self.view addSubview:button];
    [[button rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
    }];

flattenMap 将信号包装一层发送出去

[[self.phoneTextView.rac_textSignal flattenMap:^__kindof RACSignal * _Nullable(NSString * _Nullable value) {
        return [RACReturnSignal return:[NSString stringWithFormat:@"输出:%@",value]];
    }]subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];

concat:按一定顺序拼接信号,当多个信号发出的时候,有顺序的接收信号,把signalA拼接到signalB后,signalA发送完成,signalB才会被激活。订阅拼接的信号,不需要单独订阅signalA,signalB
注意:第一个信号必须发送完成,第二个信号才会被激活

 RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        
        [subscriber sendNext:@1];
        
        [subscriber sendCompleted];
        
        return nil;
    }];
    RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
       [subscriber sendNext:@2];
        return nil;
    }];
    RACSignal *concatSignal = [signalA concat:signalB];
    [concatSignal subscribeNext:^(id x) {
        NSLog(@"kl==========%@",x);
    }];

then:用于连接两个信号,当第一个信号完成,才会连接then返回的信号
then:用于连接两个信号,当第一个信号完成,才会连接then返回的信号
注意使用then,之前信号的值会被忽略掉.
底层实现:1、先过滤掉之前的信号发出的值。2.使用concat连接then返回的信号

   [[[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        [subscriber sendNext:@1];
        [subscriber sendCompleted];
        return nil;
    }] then:^RACSignal *{
        return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            [subscriber sendNext:@12];
            return nil;
        }];
    }] subscribeNext:^(id x) {
        // 只能接收到第二个信号的值,也就是then返回信号的值
        NSLog(@"then================%@",x);
    }];

merge:把多个信号合并为一个信号,任何一个信号有新值的时候就会调用,merge:把多个信号合并成一个信号,创建多个信号
底层实现:
// 1.合并信号被订阅的时候,就会遍历所有信号,并且发出这些信号。
// 2.每发出一个信号,这个信号就会被订阅
// 3.也就是合并信号一被订阅,就会订阅里面所有的信号。
// 4.只要有一个信号被发出就会被监听。

 //`merge`:把多个信号合并为一个信号,任何一个信号有新值的时候就会调用
       //merge:把多个信号合并成一个信号
       //创建多个信号
       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;
       }];
       //合并信号,任何一个信号发送数据,都能监听到.
       RACSignal *mergeSignal = [signalA merge:signalB];
       [mergeSignal subscribeNext:^(id x) {
           NSLog(@"merge==========%@\n",x);
       }];

zipWith 把两个信号压缩成一个信号,只有当两个信号同时发出信号内容时,并且把两个信号的内容合并成一个元祖,才会触发压缩流的next事件
底层实现:
// 1.定义压缩信号,内部就会自动订阅signalA,signalB
// 2.每当signalA或者signalB发出信号,就会判断signalA,signalB有没有发出个信号,有就会把最近发出的信号都包装成元组发出。

 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;
    }];
    //压缩信号A,信号B
    RACSignal *zipSignal = [signalA zipWith:signalB];
    [zipSignal subscribeNext:^(RACTwoTuple *x)
    {
        NSLog(@"zipWith============%@,%@\n\n",x.first,x.second);
    }];

combineLatest 将多个信号合并起来,并且拿到各个信号的最新的值,
// 底层实现:
// 1.当组合信号被订阅,内部会自动订阅signalA,signalB,必须两个信号都发出内容,才会被触发。
// 2.并且把两个信号组合成元组发出。

 RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        
        [subscriber sendNext:@1];
        return nil;
    }];
    
    RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        
        [subscriber sendNext:@5];
        return nil;
    }];
    
    // 把两个信号组合成一个信号,跟zip一样,没什么区别
    RACSignal *combineSignal = [signalA combineLatestWith:signalB];
    
    [combineSignal subscribeNext:^(id x) {
        
        NSLog(@"%@",x);
    }];

reduce聚合:用于信号发出的内容是元组,把信号发出元组的值聚合成一个值,聚合
常见的用法,(先组合在聚合)。combineLatest:(id)signals reduce:(id (^)())reduceBlock
// reduce中的block简介:
// reduceblcok中的参数,有多少信号组合,reduceblcok就有多少参数,每个参数就是之前信号发出的内容
// reduceblcok的返回值:聚合信号之后的内容。
底层实现:订阅聚合信号,每次有内容发出,就会执行reduceblcok,把信号内容转换成reduceblcok返回的值

 RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
         [subscriber sendNext:@1];
         return nil;
     }];
       RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber)
     {
         [subscriber sendNext:@8];
         return nil;
     }];
      RACSignal *reduceSignal = [RACSignal combineLatest:@[signalA,signalB] reduce:^id(NSNumber *num1 ,NSNumber *num2){

        return [NSString stringWithFormat:@"%@ %@",num1,num2];

    }];
    
     [reduceSignal subscribeNext:^(id x) {

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

filter:过滤信号,使用它可以获取满足条件的信号. 每次信号发出,会先执行过滤条件判断

    [_textField.rac_textSignal filter:^BOOL(NSString *value) {
            return value.length > 3;
    }];

ignore:忽略完某些值的信号.

  [[_phoneTextView.rac_textSignal ignore:@"1"] subscribeNext:^(id x) {

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

distinctUntilChanged:当上一次的值和当前的值有明显的变化就会发出信号,否则会被忽略掉。
// 过滤,当上一次和当前的值不一样,就会发出内容。
// 在开发中,刷新UI经常使用,只有两次数据不一样才需要刷新

 [[_phoneTextView.rac_textSignal distinctUntilChanged] subscribeNext:^(id x) {

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

take:从开始一共取N次的信号 1、创建信号

//    RACSubject *signal = [RACSubject subject];
//
//    // 2、处理信号,订阅信号
//    [[signal take:3] subscribeNext:^(id x) {
//
//        NSLog(@"%@",x);
//    }];
//
//    // 3.发送信号
//    [signal sendNext:@1];
//
//    [signal sendNext:@6];
//     [signal sendNext:@61];
    
    
//    takeLast:取最后N次的信号,前提条件,订阅者必须调用完成,因为只有完成,就知道总共有多少信号.
 // 1、创建信号
//    RACSubject *signal = [RACSubject subject];
//
//    // 2、处理信号,订阅信号
//    [[signal takeLast:1] subscribeNext:^(id x) {
//
//        NSLog(@"%@",x);
//    }];
//
//    // 3.发送信号
//    [signal sendNext:@1];
//
//    [signal sendNext:@2];
//[signal sendNext:@232];
//    [signal sendCompleted];
    
//    takeUntil:(RACSignal *):获取信号直到某个信号执行完成

takeUntil 当当前对象被销毁时,停止执行

 [_textField.rac_textSignal takeUntil:self.rac_willDeallocSignal];

skip:(NSUInteger):跳过几个信号,不接受

 [_phoneTextView.rac_textSignal skip:1] subscribeNext:^(id x) {
        NSLog(@"%@",x);
  }];

switchToLatest 用于signalOfSignals(信号的信号),有时候信号也会发出信号,会在signalOfSignals中,获取signalOfSignals发送的最新信号。

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

    // 获取信号中信号最近发出信号,订阅最近发出的信号。
    // 注意switchToLatest:只能用于信号中的信号
    [signalOfSignals.switchToLatest subscribeNext:^(id x) {


        NSLog(@"%@",x);
    }];
    [signalOfSignals sendNext:signal];
    [signal sendNext:@1];

ReactiveCocoa操作方法之秩序。
doNext: 执行Next之前,会先执行这个Block
doCompleted: 执行sendCompleted之前,会先执行这个Block

    [[[[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        [subscriber sendNext:@1];
        [subscriber sendCompleted];
        return nil;
    }] doNext:^(id x) {
        // 执行[subscriber sendNext:@1];之前会调用这个Block
        NSLog(@"doNext");;
    }] doCompleted:^{
        // 执行[subscriber sendCompleted];之前会调用这个Block
        NSLog(@"doCompleted");;
        
    }] subscribeNext:^(id x) {
        
        NSLog(@"%@",x);
    }];

ReactiveCocoa操作方法之线程

deliverOn: 内容传递切换到制定线程中,副作用在原来线程中,把在创建信号时block中的代码称之为副作用
 subscribeOn: 内容传递和副作用都会切换到制定线程中。

数组操作

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

    [numbers.rac_sequence.signal subscribeNext:^(id  _Nullable x) {

        NSLog(@"数据=======%@\n",x);
    }];

字典操作

 
    NSDictionary *dict = @{@"name":@"xmg",@"age":@10};

    [dict.rac_sequence.signal subscribeNext:^(RACTuple *x) {

        RACTupleUnpack(NSString *key,NSString *value) = x;

        NSLog(@"===%@",key);

        NSLog(@"=====%@",value);


    }];

map 映射成新的数据

NSArray *numbers = @[@1,@2,@3,@4];
NSArray *numbers2 =  [[numbers.rac_sequence map:^id _Nullable(id  _Nullable value) {

        return value;
    }]array] ;

RACCommand 命令执行

mand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id  _Nullable input) {

        return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {

            [subscriber sendNext:@"请求数据"];

            [subscriber sendCompleted];

            return nil;
        }];
    }];


    self.command = command;
    
    
    

//    self.btnClick.rac_command = command;

//    [self.btnClick.rac_command.executionSignals subscribeNext:^(RACSignal<id> * _Nullable x) {
//
//        NSLog(@"===%@\n",x);
//
//        [x subscribeNext:^(id  _Nullable x) {
//
//            NSLog(@"2222===%@\n",x);
//
//        }];
//    }];

   [self.command.executionSignals.switchToLatest subscribeNext:^(id  _Nullable x) {

       NSLog(@"4444===%@\n",x);
   }];
   [[command.executing skip:1] subscribeNext:^(id x) {
//
//      if ([x boolValue] == YES) {
//          // 正在执行
//          NSLog(@"正在执行");
//
//      }else{
//          // 执行完成
//          NSLog(@"执行完成");
//      }
//
//  }];
 [self.command execute:@1];

1.代替代理
// 需求:自定义redView,监听红色view中按钮点击
// 之前都是需要通过代理监听,给红色View添加一个代理属性,点击按钮的时候,通知代理做事情
// rac_signalForSelector:把调用某个对象的方法的信息转换成信号,就要调用这个方法,就会发送信号。
// 这里表示只要redV调用btnClick:,就会发出信号,订阅就好了。

 [[redV rac_signalForSelector:@selector(btnClick:)] subscribeNext:^(id x) {
//         NSLog(@"点击红色按钮");
//     }];
// 2.KVO
//     // 把监听redV的center属性改变转换成信号,只要值改变就会发送信号
//     // observer:可以传入nil
//     [[redV rac_valuesAndChangesForKeyPath:@"center" options:NSKeyValueObservingOptionNew observer:nil] subscribeNext:^(id x) {
//
//         NSLog(@"%@",x);
//
//     }];

//    // 把按钮点击事件转换为信号,点击按钮,就会发送信号
//    [[self.btn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(id x) {
//
//        NSLog(@"按钮被点击了");
//    }];
//
//    // 4.代替通知
//    // 把监听到的通知转换信号
//    [[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardWillShowNotification object:nil] subscribeNext:^(id x) {
//        NSLog(@"键盘弹出");
//    }];
    
    
//    // 6.处理多个请求,都返回结果的时候,统一做处理.
//        RACSignal *request1 = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
//
//            // 发送请求1
//            [subscriber sendNext:@"发送请求1"];
//            return nil;
//        }];
//
//        RACSignal *request2 = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
//            // 发送请求2
//            [subscriber sendNext:@"发送请求2"];
//            return nil;
//        }];
//
//        // 使用注意:几个信号,参数一的方法就几个参数,每个参数对应信号发出的数据。
//        [self rac_liftSelector:@selector(updateUIWithR1:r2:) withSignalsFromArray:@[request1,request2]];

属性绑定

 RAC(self.labelView,text) = _textField.rac_textSignal;
 [RACObserve(self.view, center) subscribeNext:^(id x) {

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

将数据包装成元祖

RACTuple *tuple = RACTuplePack(@10,@20);
TupleUnpack(NSString *number) = tuple;

    [[[tuple.rac_sequence map:^id _Nullable(id  _Nullable value) {

        return value;
    }]signal]subscribeNext:^(id  _Nullable x) {
        NSLog(@"number============%@\n",x);
    }];

throttle 节流,当某个信号发送比较频繁的时候,可以使用节流

//    节流:当某个信号发送比较频繁时,可以使用节流,在某一段时间不发送信号内容,过了一段时间获取信号的最新内容发出。
//    RACSubject *subject = [RACSubject subject];
//    // 节流1秒,1秒后接收最后一个发送的信号
//    [[subject throttle:1] subscribeNext:^(id x) {
//        NSLog(@"%@", x);
//    }];
//    [subject sendNext:@1];
//    [subject sendNext:@2];
//    [subject sendNext:@3];
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章