美文网首页
RAC 基础

RAC 基础

作者: LeeDev | 来源:发表于2017-08-03 16:42 被阅读36次
1.signal
这里有个两个知识点 
1.冷信号、热信号:只要订阅了当前的信号才会变成热信号
2.`subscriber sendError` 和 ‘subscriber subscribeCompleted’ 是互斥的,
就是说不能同时存在
3.‘RACDisposable disposableWithBlock’ 这个回调的block,是解除订阅的回调


- (void)normalSignalTest1 {
    
    //1。创建信号 ,默认是冷信号,只要穿件了才会真正的去调用
    RACSignal * signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        
        
        [subscriber sendNext:@"test msg"];
//        [subscriber sendCompleted];
        [subscriber sendError:[NSError errorWithDomain:@"" code:-1 userInfo:@{NSLocalizedDescriptionKey:@"错误描述"}]];
        return [RACDisposable disposableWithBlock:^{
            
            NSLog(@"销毁 当前的 订阅");
        }];
    }];
    //订阅以后才会成为一个热信号
    [signal subscribeNext:^(id  _Nullable x) {
        
        NSLog(@"x = %@",x);
    }];
//    [signal subscribeCompleted:^{
//       
//        NSLog(@"信号发送成功");
//    }];
    [signal subscribeError:^(NSError * _Nullable error) {
       
        NSLog(@"信号发送失败:%@",error);
    }];
    
    self.signal = signal;
    
    
}

2.RACSubject
@interface RACSubject<ValueType> : RACSignal<ValueType> <RACSubscriber>

/// Returns a new subject.
+ (instancetype)subject;

// Redeclaration of the RACSubscriber method. Made in order to specify a generic type.
- (void)sendNext:(nullable ValueType)value;

@end
RACSubject是继承与RACSignal,
并遵循< RACSubscriber >协议,
说明RACSubject 就是一个信号量,并且可以发送信号量让自己通过订阅来捕获。
这样做一个回调是很简单的

比如在第一个控制器 监听 下一个控制器(TestViewController)的点击事件

TestViewController * test = segue.destinationViewController;
        test.subject = [RACSubject subject];
        [test.subject subscribeNext:^(id  _Nullable x) {
           
            NSLog(@"revice message:%@",x);
        }];

以及点击事件的回调
- (IBAction)clickAction:(id)sender {
    
    if (self.subject) {
        [self.subject sendNext:@"From_TestViewController"];
    }
}


3.RACTuple 元组类似一个数据的包装 ,类似是Dic的封装;Sequence,就是类似一个数组的概念
    NSDictionary * dic = @{@"name":@"leeDev",@"age":@(25)};
    [dic.rac_sequence.signal subscribeNext:^(RACTuple *x) {
       
        RACTupleUnpack(NSString * key,NSString * value) = x;
//        NSLog(@"key = %@",x[0]);
//        NSLog(@"value = %@",x[1]);
        
        NSLog(@"key = %@",key);
        NSLog(@"value = %@",value);
    }];
    
    
    NSArray * arr = @[@"lee",@"lee2",@"lee3"];
    [arr.rac_sequence.signal subscribeNext:^(id  _Nullable x) {
       
        NSLog(@"x = %@",x);
    }];
4.RACCommand (我是用一个btn事件来触发)
    RACCommand * command = [[RACCommand alloc]initWithSignalBlock:^RACSignal * _Nonnull(id  _Nullable input) {
        
        //这个可以是一个btn 也可以是 一个字符串
        NSLog(@"input = %@",input);
        
        return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
            
            for (NSInteger i = 0; i < 30; i++) {
                
                [subscriber sendNext:[NSString stringWithFormat:@"comand_msg_%@",@(i)]];
            }
            [subscriber sendCompleted];
            return [RACDisposable disposableWithBlock:^{
               
                NSLog(@"某一次订阅执行完毕");
            }];
        }];
    }];
    
    self.btn.rac_command = command;
    [command.executionSignals subscribeNext:^(id  _Nullable x) {
       
        [x subscribeNext:^(id  _Nullable x) {
            
            NSLog(@"x = %@",x);
        }];
    }];
    
    //获取当前最新的信号
    [command.executionSignals.switchToLatest subscribeNext:^(id  _Nullable x) {
        
        NSLog(@"switchToLatest_x = %@",x);
    }];
    
    //执行状态,默认开始一注册就会有个信号过来,所以可以通过skip跳过第一个信号
    [[command.executing skip:1] subscribeNext:^(NSNumber * _Nullable x) {
       
        if (x.boolValue) {
            
            NSLog(@"正在执行");
        } else {
            NSLog(@"执行完毕");
        }
    }];
    
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        
        [command execute:@"主动的signal"];
    });
 
4.IOS 代理、KVO、Noti、事件状态点击 的替换
1. rac_signalForSelector需要注意
 ‘ test’对象里面包含‘ clickAction:’方法
可以代替代理(但是设计到同步的问题也是可以代替??,后面来研究一下)
[[test rac_signalForSelector:@selector(clickAction:)] subscribeNext:^(RACTuple * _Nullable x) {
           
            NSLog(@"x = %@",x);
        }];
//2.kvo
    [[self.testBtn rac_valuesAndChangesForKeyPath:@"center" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld observer:self] subscribeNext:^(RACTwoTuple<id,NSDictionary *> * _Nullable x) {
        
        NSLog(@"x = %@",x[0]);
        NSLog(@"x = %@",x[1]);
    }];
    
    [UIView animateWithDuration:2 animations:^{
       
        CGPoint center = self.testBtn.center;
        center.x += 50;
        self.testBtn.center = center;
        
    }];
    
    //3.事件处理
    [[self.testBtn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
       
        NSLog(@"x = %@",x);
    }];
    
    //4.文字的输入状态
    [[self.inputTextField rac_textSignal] subscribeNext:^(NSString * _Nullable x) {
       
        NSLog(@"x = %@",x);
    }];
    //5.键盘的处理 代替 通知
    [[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardWillShowNotification object:nil] subscribeNext:^(NSNotification * _Nullable x) {
        
        NSLog(@"x = %@",x);
    }];

5.同步处理
- (void)signalSynonization {
    
    
    RACSignal * signal1 = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        
       
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            
            [subscriber sendNext:@"signal1_send"];
            [subscriber sendCompleted];
        });
        return [RACDisposable disposableWithBlock:^{
            
            NSLog(@"signal1该次的订阅已经结束");
        }];
    }];
    
    RACSignal * signal2 = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            
            [subscriber sendNext:@"signal2_send"];
        });
        return [RACDisposable disposableWithBlock:^{
            
            NSLog(@"signal2该次的订阅已经结束");
        }];
    }];
    
    //这里一定要接受多个参数,否则会崩溃
    [self rac_liftSelector:@selector(uploadWithS1:S2:) withSignalsFromArray:@[signal1,signal2]];
    
}

- (void)uploadWithS1:(id)data S2:(id)data2 {
    

    NSLog(@"data = %@",data);
    NSLog(@"data2 = %@",data2);
}

6. 常见宏
//Target ,property
 RAC(self.testLabel,text) = self.inputTextField.rac_textSignal;
    [RACObserve(self.testBtn,center) subscribeNext:^(id  _Nullable x) {
        
        NSLog(@"x = %@",x);
    }];

@weakify(Obj)和 @strongify(Obj)

//Tuple 打包
RACTuple *tuple = RACTuplePack(@10,@20);
//Tuple 解包
RACTupleUnpack(NSString *name,NSNumber *age) = tuple;

学习RAC 链接
http://www.jianshu.com/p/87ef6720a096
http://benbeng.leanote.com/post/ReactiveCocoaTutorial-part2
http://www.cocoachina.com/ios/20150817/13071.html

相关文章

  • RAC 详细解析

    RAC详细解析(一)—— 框架概览RAC详细解析(二)—— 基础使用方法

  • RAC基础

    获得信号的方式 1.Cocoa桥接 2.信号变换 3.序列转换RACSignal * sig4 = [RACSeq...

  • RAC基础

    RAC(ReactiveCocoa) 简单的说,RAC就是一个第三方库,他可以大大简化你的代码过程。 官方的说,R...

  • RAC 基础

    1.signal 2.RACSubject 3.RACTuple 元组类似一个数据的包装 ,类似是Dic的封装;S...

  • RAC基础

    RAC是一套基于Cocoa的FRP框架,它的优点是用户的输入转化为随时间改变的函数,取消了可变状态.在RAC的世界...

  • RAC基础

    最近接触学习到了RAC(ReactiveCocoa),RAC是函数式+响应式编程结合 我们在iOS开发中,页面之间...

  • 收录 : iOS - ReactiveCocoa(RAC)

    美团RAC技术文档 ReactiveCocoa基础ReactiveCocoa进阶 ReactiveCocoa教程:...

  • ReactiveObjC(RAC)基础

    最近学习了一下RAC的使用,参考了下面两篇文章 Jonzzs的【iOS 开发】ReactiveObjC(RAC)的...

  • iOS RAC学习

    一、RAC使用基础认知 RAC编程思想:响应式编程+函数式编程 在iOS中,类之间的传值,无非就是block、de...

  • 菜鸟用RAC基于AFNetworking 3.0网络的封装搭建记

    前言 这几天自己在学习RAC,学习了几天对RAC有了一定基础了解,如之前写的菜鸟开始学习ReactiveObjc运...

网友评论

      本文标题:RAC 基础

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