ReactiveCocoa 初识(一)

    入职有一段时间了,没有开发任务,白天就看看博客写写自己的东西,晚上看世界杯,简直不要太爽,就是天台有点挤了(╯3╰)。
    最近在学习ReactiveCocoa,项目导入ReactiveObjC开干。

RACSignal
    RACSignal是RAC核心的类,使用的时候先创建信号,订阅信号,在创建信号的block里面发送信号。

- (void)RACSignal
{
    //1 创建信号
    RACSignal * signal = [RACSignal createSignal:^RACDisposable * _Nullable(id  _Nonnull subscriber) {
        
        //3 发送信号
        [subscriber sendNext:@"发送信号"];
        
        return [RACDisposable disposableWithBlock:^{
            NSLog(@"取消订阅");
        }];
//        return nil;
    }];
    
    //2 订阅信号
    RACDisposable * disposable = [signal subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
    
    //4 取消订阅
    [disposable dispose];
}

RACSubject
    RACSubject是继承自RACSignal,同时也遵循RACSubscriber协议。所以RACSubject既可以订阅信号,也能发送信号。使用方法也是先订阅后发送。它和RACReplaySubject的区别是,RACReplaySubject可以先发送后订阅。

- (void)RACSubject
{    
    //1 创建信号
    RACSubject * subject = [RACSubject subject];
    
    //2 订阅信号
    [subject subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
    
    //3 发送信号
    [subject sendNext:@"发送信号"];
}

RACSequence
    RACSequence一般用于遍历数组和字典等容器类,RAC扩展了一种数据类型Tuple元祖,接触过Swift的一定不会陌生。

- (void)RACSequence
{
    //遍历
    
    NSArray * array = @[@"1",@"2",@"3",@"3",@"5"];
    [array.rac_sequence.signal subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
    
    //元祖
    RACTuple * tuple = RACTuplePack(array);
    NSLog(@"%@",tuple[0]);
    NSLog(@"%@",[tuple first]);
    NSLog(@"%@",[tuple last]);
    
    NSDictionary * dict = @{@"key1":@"value1",@"key2":@"value2"};
    [dict.rac_sequence.signal subscribeNext:^(id  _Nullable x) {
        RACTupleUnpack(NSString * key,NSString * value) = x;
        NSLog(@"%@  %@",key,value);
    }];
    
    //替换数组的元素 生成新的数组 单个操作
    NSArray * newArray1 = [[array.rac_sequence map:^id _Nullable(id  _Nullable value) {
        return @"0";
    }] array];
    NSLog(@"%@",newArray1);
    
    //替换数组的元素 生成新的数组 全部操作
    NSArray * newArray2 = [[array.rac_sequence mapReplace:@"1"] array];
    NSLog(@"%@",newArray2);
}

RACMulticastConnection
    ReactiveCocoa中信号默认都是冷的,每次有新的订阅者订阅信号的时候都会执行信号创建时传入的block。举个例子,把一个网络请求的结果设置为信号,多个UI订阅了这个信号,每次订阅的时候,都会进行一次网络请求。

RACSignal * signal = [RACSignal createSignal:^RACDisposable * _Nullable(id  _Nonnull subscriber) {
        /*网络请求*/
        [subscriber sendNext:@"发送信号"];
        return nil;
    }];
    
    [signal subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
    
    [signal subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
    
    [signal subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];

    为了避免这一情况,使用RACMulticastConnection,创建链接类,将订阅者连接起来,把信号源变成热信号。

- (void)RACMulticastConnection
{
    //多个订阅者 只发一个信号
    RACSignal * signal = [RACSignal createSignal:^RACDisposable * _Nullable(id  _Nonnull subscriber) {
        [subscriber sendNext:@"发送信号"];
        return nil;
    }];
    
    //创建链接类
    RACMulticastConnection * connection = [signal publish];
    
    [connection.signal subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
    
    [connection.signal subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
    
    [connection.signal subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
    
    //连接 把信号源变为热信号
    [connection connect];
}

merge
    信号的合并

- (void)merge
{
    RACSubject * subject1 = [RACSubject subject];
    RACSubject * subject2 = [RACSubject subject];
    RACSubject * subject3 = [RACSubject subject];
    
    [[RACSignal merge:@[subject1,subject2,subject3]] subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
    
    [subject1 sendNext:@"subject1"];
    [subject2 sendNext:@"subject2"];
    [subject3 sendNext:@"subject3"];
}

group
    类似于GCD的任务组,完成多个任务后才能执行某个方法

- (void)group
{
    RACSignal * signalA = [RACSignal createSignal:^RACDisposable * _Nullable(id  _Nonnull subscriber) {
        /*网络请求1*/
        [subscriber sendNext:@"请求1完成"];
        return nil;
    }];
    
    RACSignal * signalB = [RACSignal createSignal:^RACDisposable * _Nullable(id  _Nonnull subscriber) {
        /*网络请求2*/
        [subscriber sendNext:@"请求2完成"];
        return nil;
    }];
    
    [self rac_liftSelector:@selector(dependSignalA:WithSignalB:) withSignalsFromArray:@[signalA,signalB]];
}

- (void)dependSignalA:(NSString *)str1 WithSignalB:(NSString *)str2
{
    
}

Notification && KVO
    RAC来替换Notification和KVO的

- (void)Notification
{
    //不用写removeObserver
    [[[NSNotificationCenter defaultCenter] rac_addObserverForName:@"NotificationName" object:nil] subscribeNext:^(NSNotification * _Nullable x) {
        NSLog(@"%@",x);
    }];
}

- (void)KVO
{
    [[self.view rac_valuesForKeyPath:@"color" observer:self] subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
}

Timer
    RAC实现一个Timer的功能

- (void)Timer
{
    RACDisposable * disposable = [[RACSignal interval:1.f onScheduler:[RACScheduler mainThreadScheduler]] subscribeNext:^(NSDate * _Nullable x) {
        //当前时间
        NSLog(@"%@",x);
        
        [disposable dispose];
    }];
}

UI
    再来看看RAC在UI上的一些应用

- (void)UI
{
    UITextField * tf = [UITextField new];
    UITextField * tf2 = [UITextField new];
    UIButton * btn = [UIButton new];
    
    [[tf rac_textSignal] subscribeNext:^(NSString * _Nullable x) {
        NSLog(@"%@",x);
    }];
    
    //filter 和 ignore
    [[[tf2.rac_textSignal filter:^BOOL(NSString * _Nullable value) {
        return value.length > 6;
    }] ignore:@"666"] subscribeNext:^(NSString * _Nullable x) {
        NSLog(@"%@",x);
    }];
    
    //响应事件
    [[btn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
        NSLog(@"%@",x);
    }];
    
    //两个输入框长度大于3的时候 按钮才可以点击
    RAC(btn,enabled) = [RACSignal combineLatest:@[tf.rac_textSignal,tf2.rac_textSignal] reduce:^id (NSString * str1, NSString * str2){
        return @(str1.length > 3 && str2.length > 3);
    }];
}

    ReactiveCocoa是个响应式编程框架,在iOS中没有接触过类似的代码。不过之前有接触过AngularJS,对里面ng-Model指令,单向绑定、双向绑定有一定的了解。下篇会重点理解RACCommand,结合一个登录的Demo来实践。
    代码: ReactiveObjCDemo

你可能感兴趣的:(ReactiveCocoa 初识(一))