美文网首页
ReactiveCocoa快速上手

ReactiveCocoa快速上手

作者: 炒鸡范 | 来源:发表于2016-02-24 19:24 被阅读125次

    本文是我在学习ReactiveCocoa的过程中的总结记录

    一,引入ReactiveCocoa框架

    pod 'ReactiveCocoa'
    #import <ReactiveCocoa/ReactiveCocoa.h>

    二,常见类的使用

    1.RACSignal

    RACSignal是RAC中最常见的类,做个简单的实验

    
    -(void)testRACSignal
    {
        //第一步
        RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            [subscriber sendNext:@1];
            [subscriber sendCompleted];
            return [RACDisposable disposableWithBlock:^{
                NSLog(@"信号销毁");
            }];
        }];
        
        //第二步
        [signal subscribeNext:^(id x) {
            NSLog(@"接收到数据:%@",x);
        }];
    }
    

    执行这个函数,可以看到结果如下:

    2016-02-24 15:11:06.950 FL_RAC_DEMO[101:3360025] 接收到数据:1
    2016-02-24 15:11:06.951 FL_RAC_DEMO[101:3360025] 信号被销毁
    

    大致可以理解为,在第一步中,创建一个信号 传入的block是当这个信号被订阅后会自动执行的代码。第二步中订阅了这个信号,此时block执行,其中的[subscriber sendNext:@1];会被发送给第二步中的block接收。

    2.RACSubject

    -(void)testRACSubject
    {
        RACSubject *subject = [RACSubject subject];
        [subject subscribeNext:^(id x) {
            NSLog(@"第一个订阅者%@",x);
        }];
        [subject subscribeNext:^(id x) {
            NSLog(@"第二个订阅者%@",x);
        }];
        
        [subject sendNext:@"1"];
    }
    

    执行这个函数,可以看到结果如下:

    2016-02-24 15:11:32.114 FL_RAC_DEMO[139:3360495] 第一个订阅者1
    2016-02-24 15:11:32.114 FL_RAC_DEMO[139:3360495] 第二个订阅者1
    

    RACSubject可以即使信号发送者,也是信号接受者
    在实际使用中常备用来作为代理的替代方式,我们可以做以下实验:
    新建一个TestRACSubjectDelegate类

    #import <Foundation/Foundation.h>
    //引入ReactiveCocoa框架
    #import <ReactiveCocoa/ReactiveCocoa.h>
    
    @interface TestRACSubjectDelegate : NSObject
    
    @property(strong,nonatomic)RACSubject *delegateSubject;
    
    @end
    
    
    
    #import "TestRACSubjectDelegate.h"
    
    @implementation TestRACSubjectDelegate
    - (instancetype)init
    {
        self = [super init];
        if (self) {
    
            _delegateSubject = [RACSubject subject];
            
            [self performSelector:@selector(doSomething) withObject:nil afterDelay:2];
        }
        return self;
    }
    
    -(void)doSomething
    {
        [_delegateSubject sendNext:@1];
    }
    @end
    

    在ViewController中

    -(void)testRACSubjectAsDelegate
    {
        TestRACSubjectDelegate *subject = [[TestRACSubjectDelegate alloc] init];
        [subject.delegateSubject subscribeNext:^(id x) {
            NSLog(@"收到了数据:%@",x);
        }];
    }
    

    执行这个函数,可以看到结果如下:

    2016-02-24 15:28:49.312 FL_RAC_DEMO[489:3371887] 收到了数据:1
    

    所以RACSubject是作为代理的一种很好的替代方式

    3.RACCommand

    RACCommand可以将某些事件进行包装处理

    -(void)testRACCommand
    {
        RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
    
            NSLog(@"执行命令");
            
            RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
                [subscriber sendNext:@"请求数据"];
                [subscriber sendCompleted];
                return [RACDisposable disposableWithBlock:^{
                    NSLog(@"信号已销毁");
                }];
            }];
         
            return signal;
        }];
        
        //必须对command进行强应用,否则会接收不到数据
        _command = command;
        
        [command.executionSignals subscribeNext:^(id x) {
            [x subscribeNext:^(id x) {
                NSLog(@"=>%@",x);
            }];
            
        }];
        
        [self.command execute:@1];
    }
    

    执行这个函数,可以看到结果如下:

    2016-02-24 18:30:51.303 FL_RAC_DEMO[1133:3435749] 执行命令
    2016-02-24 18:30:51.311 FL_RAC_DEMO[1133:3435749] =>请求数据
    2016-02-24 18:30:51.312 FL_RAC_DEMO[1133:3435749] 信号已销毁
    

    在做网络请求或者对按钮状态处理会经常使用RACCommand

    4.其他常用

    -(void)testOther
    {
        //_testView中的按钮点击事件调用clickBtn,可以不实现函数直接在这里被检测到,用来替代代理的功能
        [[_testView rac_signalForSelector:@selector(clickBtn:)] subscribeNext:^(id x) {
            NSLog(@"点击按钮");
        }];
        
        // KVO
        [[_testView rac_valuesAndChangesForKeyPath:@"center" options:NSKeyValueObservingOptionNew observer:nil] subscribeNext:^(id x) {
            NSLog(@"%@",x);
        }];
        
        // 按钮点击事件
        [[self.btn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(id x) {
            NSLog(@"按钮被点击");
        }];
        
        // 通知
        [[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardWillShowNotification object:nil] subscribeNext:^(id x) {
            NSLog(@"键盘弹出");
        }];
        
        //文本框的文字改变
        [_textField.rac_textSignal subscribeNext:^(id x) {
            NSLog(@"文字改变了%@",x);
        }];
        
        // 多个信号合并处理
        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()

    // 只要文本框文字改变,就会修改label的文字 
    RAC(self.labelView,text) = _textField.rac_textSignal;
    

    RACObserve()

    [RACObserve(self.view, center) subscribeNext:^(id x) { NSLog(@"%@",x); }];
    

    感谢:
    http://www.jianshu.com/p/87ef6720a096

    相关文章

      网友评论

          本文标题:ReactiveCocoa快速上手

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