iOS ReactiveCocoa学习

简介

ReactiveCocoa是github开源的一个第三方框架,响应式编程的代表。通过函数式响应式编程的思想,实现的信号机制。使用ReactiveCocoa去搭建MVVM架构,使代码更加高聚合,低耦合。便捷的实现双向绑定的效果。

集成

swift项目

pod 'ReactiveCocoa'

OC项目

pod 'ReactiveObjC'

swift与OC混编项目

pod 'ReactiveObjC'
pod 'ReactiveCocoa'
pod 'ReactiveObjCBridge'

常用类

RACSiganl信号类

    //核心:信号类
    //信号类作用:只要有数据改变,就会把数据长成一个信号,传递出去。
    //只要有数据改变,就会有信号发出。
    //数据发出,并不是信号类发出。
    
    //创建信号
    //RACDisposable
    //RACSubscriber
    
    //createSignal方法:
    //1.创建RACDynamicSignal
    //2.把didSubscribe保存到RACDynamicSignal
    RACSignal *singal = [RACSignal createSignal:^RACDisposable * _Nullable(id  _Nonnull subscriber) {
        
        //block:当信号被订阅的时候就会调用
        //block作用:描述当前信号哪些数据需要发送
        
        //发送数据
        NSLog(@"调用了didSubscribe");
        //通常:传递数据出去。 发送
        [subscriber sendNext:@1];
        
        //如果信号被取消,就必须返回一个RACDisposable
        return [RACDisposable disposableWithBlock:^{
            
            //信号什么时候被取消: 1.自动取消:当一个信号订阅者subscriber被销毁时,就会自动取消订阅 2.手动取消
            //block调用时刻:一旦一个信号被取消的时候就会调用
            //block作用:当信号取消订阅时,用于清空一些资源
            NSLog(@"取消了");
        }];
    }];
    
    //订阅信号
    //    [singal subscribeNext:^(id  _Nullable x) {
    //        NSLog(@"%@",x);
    //    }];
    //只要订阅信号,就会返回一个取消信号的类
    RACDisposable *disposable = [singal subscribeNext:^(id  _Nullable x) {
        //block:只要信号内部发送数据,就会调用这个block
        NSLog(@"%@",x);
    }];
    
    //取消订阅
    [disposable dispose];
    
    //使用步骤
    //1.创建信号
    //2.订阅信号
    
    // RACSingal底层实现
    //1.当一个信号被订阅的时候,创建订阅者,并且把nextBlock保存到订阅者里面
    //2.RACDynamicSignal subscribe:(id)subscriber
    //3.调用RACDynamicSignal的didSubscribe
    //4.[subscriber sendNext:@1];
    //5.拿到订阅者的nextBlock调用。

RACSubject :信号提供者

    //1.创建信号
    RACSubject *subject = [RACSubject subject];
    /*
     //取消订阅用
     _disposable = [RACCompoundDisposable compoundDisposable];
     //确定容量 分配不同的内存 1.节约内存,2.提高性能
     _subscribers = [[NSMutableArray alloc] initWithCapacity:1];
     */
    
    
    
    //2.订阅信号
    //创建一个数组在信号对象中,
    //创建一个订阅者对象,将block回调保存到订阅者中,
    //将订阅者保存到已经创建好的数组中。
    [subject subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
    
    //3.发送信号
    //遍历装有订阅者对象的数组,拿到这个订阅者对象,
    //将block的内容拷贝,将value作为参数传入block,并且调用block执行
    [subject sendNext:@"哈哈"];

RACReplaySubject:重复提供信号类

    //RACReplaySubject:重复提供信号类
    //如果一个信号每被订阅一次,就需要把之前的值重复发送一遍,使用重复信号类
    
    //创建信号
    RACReplaySubject *replaySubject = [RACReplaySubject subject];
    
    //订阅信号
    //第一个订阅者
    [replaySubject subscribeNext:^(id  _Nullable x) {
        NSLog(@"111111%@",x);
    }];
    //第二个订阅者
    [replaySubject subscribeNext:^(id  _Nullable x) {
        NSLog(@"22222%@",x);
    }];
    
    //发送信号
    [replaySubject sendNext:@77];

RACSequence:RAC中的集合类

    //RACSequence:RAC中的集合类,用于代替数组和字典,可以进行快速遍历
    NSArray *numbers = @[@1,@2,@3,@4,@5];
    
    //.rac_sequence把数组转换成RAC中的集合类RACSequence
    //把RACSequence转换成信号
    [numbers.rac_sequence.signal  subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
    
    NSDictionary *dict = @{@"jack" : @"max",
                          @"andy" : @"min"
                           };
    [dict.rac_sequence.signal subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
        //RACTuple元组
        RACTuple *touple = x;
        NSLog(@"%@------%@",touple.first,touple.second);
        
        //RACTupleUnpack 专门用来解析元组
        RACTupleUnpack(NSString *key, NSString *value) = x;
        NSLog(@"解析元组%@---%@",key,value);
    }];

RACCommand 命令类

    //RACCommand 命令类
    
    //使用注意:RACCommand中的block不能返回一个nil的i信号
    //创建命令类
    RACCommand  *command = [[RACCommand alloc]initWithSignalBlock:^RACSignal * _Nonnull(id  _Nullable input) {
        //block什么时候调用:当执行这个命令类的时候调用
        NSLog(@"执行命令");
        //block作用:描述下如何处理事件, 网络请求
        NSLog(@"%@",input);
        
        //返回数据
        
        //为什么RACCommand必须返回信号
        //处理事件的时候,肯定会有数据产生,产生的数据就通过返回的信号发出
        return [RACSignal createSignal:^RACDisposable * _Nullable(id  _Nonnull subscriber) {
            
            //block作用:发送处理事件的信号
            //block调用:当信号被订阅的时候才会调用
            [subscriber sendNext:@"网络请求的数据"];
            
            return nil;
        }];
    }];
    
    //executionSignals信号源,包含事件处理的所有信号
    //executionSignals:信号中的信号
    //如果想接收信号源的信号内容,必须保证命令不会被销毁。 所以需要创建全局的RACCommand。
    [command.executionSignals subscribeNext:^(id  _Nullable x) {
        RACSignal *singal = x;
        [singal subscribeNext:^(id  _Nullable x) {
            NSLog(@"信号中的信号解析的数据%@",x);
        }];
    }];
    
    //执行命令,调用signalBlock
    [command execute:@9090];

RACMulticastConnection

    //RACMulticastConnection:用于当一个信号,被多次订阅时,为了保证创建信号时,避免多次调用创建信号中的block,造成副作用,可以使用这个类处理。
    
    RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id  _Nonnull subscriber) {
        NSLog(@"发送数据哈哈哈哈");
        [subscriber sendNext:@6666];
        return nil;
    }];
    
    //连接类
    RACMulticastConnection *connection = [signal publish];
    
    //订阅信号
    [connection.signal subscribeNext:^(id  _Nullable x) {
        NSLog(@"x");
    }];
    [connection.signal subscribeNext:^(id  _Nullable x) {
        NSLog(@"x");
    }];
    
    //连接:才会把源信号编程热信号
    [connection connect];

RAC常见用法

代理

    //rac_signalForSelector 判断某个对象有没有调用他的某个方法,如果调用了,就会自动发送一个信号。
    //可以用来替换代理
    [[self rac_signalForSelector:@selector(helloTest)]subscribeNext:^(RACTuple * _Nullable x) {
        NSLog(@"当前self调用了helloTest这个方法");
    }];
    
    - (void)helloTest
    {   
    
    }

KVO

    //KVO 代替
    //监听某个对象的某个属性书否发生改变,如果发生改变,则会发送一个信号,订阅这个信号,就可以获得这个改变的值
    [[_p rac_valuesForKeyPath:NSStringFromSelector(@selector(name)) observer:nil]subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];

监听按钮

    //监听按钮 _button只要产生UIControlEventTouchUpInside这个事件就会转换成信号,订阅这个信号就可以获取。
    [[_button rac_signalForControlEvents:UIControlEventTouchUpInside]subscribeNext:^(__kindof UIControl * _Nullable x) {
        NSLog(@"点击了按钮hahaha ");
    }];

监听通知

    [[[NSNotificationCenter defaultCenter]rac_addObserverForName:UIKeyboardWillShowNotification object:nil]subscribeNext:^(NSNotification * _Nullable x) {
        NSLog(@"监听键盘状态");
    }];

监听textfield的输入内容

    //监听textfield的输入内容
    [[_testField rac_textSignal]subscribeNext:^(NSString * _Nullable x) {
        NSLog(@"输入的内容:%@",x);
    }];

多个界面都获取到数据之后,采取执行。

    //多个界面都获取到数据之后,采取执行。 多个网络请求都获取到数据之后,再做操作。
    RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id  _Nonnull subscriber) {
        
        [subscriber sendNext:@"数据11111"];
        
        return nil;
    }];
    
    RACSignal *signal2 = [RACSignal createSignal:^RACDisposable * _Nullable(id  _Nonnull subscriber) {
        
        [subscriber sendNext:@"数据22222"];
        
        return nil;
    }];
    
    //RAC 可以判断两个信号有没有都发出内容
    //当数组中的所有信号都发出的时候,self就会调用twoAll方法
    //@selector(twoAllwithOne:two:)这个方法不能乱写,有几个信号就定义几个参数
    //不需要主动订阅信号,这个方法会自动订阅这两个信号。
    [self rac_liftSelector:@selector(twoAllwithOne:two:) withSignalsFromArray:@[signal,signal2]];
    
    
    - (void)twoAllwithOne:(NSString *)oneStr two:(NSString *)twoStr
    {
    NSLog(@"两个信号都发出了 %@  ----  %@",oneStr,twoStr);
    }

RAC常用宏

    //把一个对象的某个属性绑定一个信号,只要发出信号,就会把信号的内容发送出去,给这个对象的属性赋值。
    RAC(_label,text) = _testField.rac_textSignal;
    
    //KVO 快速的监听对象的某个属性,改变的时候会发出信号。
    [RACObserve(self.view, center) subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
    
    //把self转换成弱指针 循环引用问题
    @weakify(self)
    [RACSignal createSignal:^RACDisposable * _Nullable(id  _Nonnull subscriber) {
        
        @strongify(self)
        NSLog(@"%@",self.p);
        return nil;
    }];
    
    //元组
    //包装元组
    RACTuple *tuple = RACTuplePack(@1,@3);
    NSLog(@"%@-----%@",tuple.first,tuple.second);
    //解包元组
    RACTupleUnpack(NSNumber *number1, NSNumber *number2) = tuple;
    NSLog(@"解包%@-----%@",number1,number2);

你可能感兴趣的:(iOS ReactiveCocoa学习)