ReactiveCocoa快速上手

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

一,引入ReactiveCocoa框架

pod 'ReactiveCocoa'
#import

二,常见类的使用

1.RACSignal

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


-(void)testRACSignal
{
    //第一步
    RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id 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 
//引入ReactiveCocoa框架
#import 

@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 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 subscriber) {
        
        // 发送请求1
        [subscriber sendNext:@"发送请求1"];
        return nil;
    }];
    
    RACSignal *request2 = [RACSignal createSignal:^RACDisposable *(id 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快速上手)