走进ReactiveCocoa的大门

前面也说了RAC配合MVVM使用才能发挥最大的作用,因为RAC可以在VM模块中进行业务逻辑和网络请求,所以可以说完全分担了控制器的压力。

一:RAC的核心是RACSignal类(信号)

RACSignal: 就 RAC 来说是构造单元. 它代表我们最终将要收到的信息. 当你能将未来某时刻收到的消息具体表示出来时, 你可以开始预先运用逻辑并构建你的信息流,而不是必须等到事件发生才执行。白话一点就是最后我是一定会收到消息的,所以不需要考虑我是否能收到,只需要构建信息流就行。

那么什么是信号?

其实信号就是发送一系列的值,(三种事件:next、complete、error。你可以理解为我们生活中手机信号,需要一个设备来获取信号,那么谁是设备呢?这里就需要一个订阅者来监听这个信号。

信号是一些等待某事发生的异步代码, 然后把结果值发送给它们的订阅者. 你可以用 RACSignal 的类方法 createSignal: 

 RACSignal *Signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
      NetworkOperation *operation = [NetworkOperation getJSONOperationForURL:@"http://someurl"];
      [operation setCompletionBlockWithSuccess:^(NetworkOperation *theOperation, id *result) {
            [subscriber sendNext:result];//发送信号
            [subscriber sendCompleted]; //如果不发送信号,这里就会取消信号
         }
       failure:^(NetworkOperation *theOperation, NSError *error) {
            [subscriber sendError:error];
      }];


我在成功的 block 里使用提供的 subscriber 对象调用 sendNext: 和 sendCompleted: 方法, 或在失败的 block 中调用 sendError:. 现在我可以订阅这个信号并将在响应返回时接收到 json 值或是 error。

什么是订阅者(RACSubscriber)?

简言之,  它是等待信号给它发送一些值, 然后订阅者就能处理这些值了.,可以用subscribeNext:方法来获取信息

//这里的x值就是信号发送过来的值
[Signal subscribeNext:^(id* x) {
    NSLog(@"%@",x);
}];


记下来讲解几个重要的事件:

信号延时:

<span style="font-size:18px;">  [[[RACSignal createSignal:</span><span style="font-family: Monaco, Menlo, Consolas, 'Courier New', monospace; white-space: pre-wrap;"><span style="font-size:12px;">^RACDisposable *(id<RACSubscriber> subscriber</span></span><span style="font-size:18px;">) {
        NSLog(@"等等我,我还有6秒钟就到了");
        [subscriber sendNext:nil];
        [subscriber sendCompleted];
        return nil;
    }] delay:6] subscribeNext:^(id x) {
        NSLog(@"我到了");
    }];</span>

定时:8小时之后执行一次

 [[RACSignal interval:60*60*8 onScheduler:[RACScheduler mainThreadScheduler]] subscribeNext:^(id x) {
        NSLog(@"我觉得你该喝水呢!");
    }];


超时:

[[[RACSignal createSignal:^RACDisposable *(idsubscriber) {
        [[[RACSignal createSignal:^RACDisposable *(idsubscriber) {
            NSLog(@"我快到了,在等十分钟");
            [subscriber sendNext:nil];
            [subscriber sendCompleted];
            return nil;
        }] delay:60*10] subscribeNext:^(id x) {
            NSLog(@"不好意思,让你久等了,超了两分钟");
            [subscriber sendNext:nil];
            [subscriber sendCompleted];
        }];
        return nil;
    }] timeout:60*8 onScheduler:[RACScheduler mainThreadScheduler]] subscribeError:^(NSError *error) {
        NSLog(@"等了你八分钟了,你还没来,我走了");
    }];

命令指令:

  RACCommand *aCommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
       return [RACSignal createSignal:^RACDisposable *(idsubscriber) {
           NSLog(@"我投降了");
           [subscriber sendCompleted];
           return nil;
       }];
    }];
    [aCommand execute:nil];//执行命令

过滤:

  [[[RACSignal createSignal:^RACDisposable *(idsubscriber) {
        [subscriber sendNext:@(17)];
        [subscriber sendNext:@(21)];
        [subscriber sendNext:@(14)];
        [subscriber sendNext:@(30)];
        return nil;
    }] filter:^BOOL(NSNumber* value) {
        return value.integerValue >= 18;
    }] subscribeNext:^(id x) {
        NSLog(@"%@", x);
    }];

通知:

 [[NSNotificationCenter defaultCenter] postNotificationName:@"这是我的代码" object:nil userInfo:@{@"代码":@"用心写"}];
 [[[NSNotificationCenter defaultCenter] rac_addObserverForName:@"这是我的代码" object:nil] subscribeNext:^(NSNotification* x) {
        NSLog(@"代码:%@", x.userInfo[@"代码"]);
    }];

二:RACCommand:处理事件的类,可以方便的监听事件处理过程

使用场景:网络请求

三步走:

1.创建命令 initWithSignalBlock:(RACSignal * (^)(id input))signalBlock

 2.在signalBlock中,创建RACSignal,并且作为signalBlock的返回值
3.执行命令 - (RACSignal *)execute:(id)input
使用:

 // 1.创建命令
    RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {

        NSLog(@"执行命令");
        // 2.创建信号,用来传递数据
        return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
           //这里就是网络请求得到的数据
            [subscriber sendNext:@"请求数据"];
            // 注意:数据传递完,最好调用sendCompleted,这时命令才执行完毕。
            [subscriber sendCompleted];
            return nil;
        }];
    }];

    // 强引用命令,不要被销毁,否则接收不到数据
    _conmmand = command;

    // 3.订阅RACCommand中的信号
    [command.executionSignals subscribeNext:^(id x) {

        [x subscribeNext:^(id x) {

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

    }];

    // RAC高级用法
    // switchToLatest:用于signal of signals,获取signal of signals发出的最新信号,也就是可以直接拿到RACCommand中的信号
    [command.executionSignals.switchToLatest subscribeNext:^(id x) {

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

    // 4.监听命令是否执行完毕,默认会来一次,可以直接跳过,skip表示跳过第一次信号。
    [[command.executing skip:1] subscribeNext:^(id x) {

        if ([x boolValue] == YES) {
            // 正在执行
            NSLog(@"正在执行");

        }else{
            // 执行完成
            NSLog(@"执行完成");
        }

    }];
   // 5.执行命令
    [self.conmmand execute:@1];

RAC开发中常见用法。

1 代替代理:

  • rac_signalForSelector:用于替代代理。

2 代替KVO :

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

3 监听事件:

  • rac_signalForControlEvents:用于监听某个事件。

4 代替通知:

  • rac_addObserverForName:用于监听某个通知。

5 监听文本框文字改变:

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





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值