美文网首页MVVM
RAC基本用法

RAC基本用法

作者: 天外丶飞仙 | 来源:发表于2017-04-19 21:57 被阅读52次

    最近公司要用MVVM+RAC重构项目,所以就对RAC开发中的基本用法总结了一下。

    RACSignal

    RACSignal使用步骤: 1.创建信号 2.订阅信号 3.发送信号。

    RACSignal * signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        //信号被订阅就会执行这个block
        // subscribe调用:只要一个信号被订阅就会调用
        // subscribe作用:发送数据       
        [subscriber sendNext:@"发送数据"];
        //发送完成
        [subscriber sendCompleted];
        //返回值是RACDisposable这个类
        return [RACDisposable disposableWithBlock:^{
            // block调用时刻:当信号发送完成或者发送错误,就会自动执行这个block,取消订阅信号。
            // 执行完Block后,当前信号就不在被订阅了。
            NSLog(@"信号被销毁");
        }];
    }];
    [signal subscribeNext:^(id x) {
        // nextBlock调用:只要订阅者发送数据就会调用
        // nextBlock作用:处理数据,展示到UI上面
        // x:信号发送的内容
        NSLog(@"%@",x);
    }];
    

    RACSubject

    RACSubject使用步骤: 1.创建信号 2.订阅信号 3.发送信号。

    // 1.创建信号
    RACSubject *subject = [RACSubject subject] ;
    // 2.订阅信号
    [subject subscribeNext:^(id x) {
        // block调用时刻:当信号发出新值,就会调用.
        NSLog(@" 接受到的信号%@",x);
    }];
    // 3.发送信号
    [subject sendNext:@"1"];
    

    RACReplaySubject

    RACReplaySubject使用步骤和RACSubject相同,区别在于订阅信号,发送信号可以交换顺序。

    // 1.创建信号
    RACReplaySubject *replaySubject = [RACReplaySubject subject];
    // 2.发送信号
    [replaySubject sendNext:@1];
    // 3.订阅信号
    [replaySubject subscribeNext:^(id x) {
        NSLog(@"订阅者接收到的数据%@",x);
    }];
    

    RACSequence

    可以用RACSequence来遍历数组。

    NSArray *numbers = @[@1,@2,@3,@4];
    [numbers.rac_sequence.signal subscribeNext:^(id x) {
           //拿到遍历的数组值
           NSLog(@"%@",x);
    }];
    

    用来遍历字典

     NSDictionary *dict = @{@"name":@"xmg",@"age":@18};
     [dict.rac_sequence.signal subscribeNext:^(RACTuple *x) {
            // 解包元组,会把元组的值,按顺序给参数里面的变量赋值
            RACTupleUnpack(NSString *key,NSString *value) = x;
            NSLog(@"%@ %@",key,value);
     }];
    

    RACMulticastConnection

    假设在一个信号中发送请求,每次订阅一次都会发送请求,这样就会导致多次请求。使用RACMulticastConnection不管订阅多少次,请求只发送一次。

      // 1.创建信号
    RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        NSLog(@"发送请求");
        [subscriber sendNext:@1];
        return nil;
    }];
    // 2.创建连接
    RACMulticastConnection *connect = [signal publish];
    // 3.订阅信号,
    [connect.signal subscribeNext:^(id x) {
        NSLog(@"订阅者一");
    }];
    [connect.signal subscribeNext:^(id x) {
        NSLog(@"订阅者二");
    }];
    // 4.连接,激活信号
    [connect connect];
    

    RAC开发中常用的用法

    代替代理:rac_signalForSeletor:
    代替KVO:rac_valuesAndChangesForKeyPath:
    监听事件:rac_signalForControlEvents:
    代替通知: rac_addObbserverForName:
    监听文本框文字改变: rac_textSignal:
    当一个界面多次请求时,需要都请求完成才搭建界面:
    //方法的参数必须和数组的参数一一对应
    ran_liftSelector: withSignalsFromArray:

    RAC中常用的宏

    //1. 用来给某个对象的某个属性绑定信号,只要产生信号内容,就会把内容给属性赋值
    RAC(_label,text) = _textField.rac_textSignal;
    
    //2.只要这个对象的属性一改变就会产生信号
    [RACObserve(self.view, frame) subscribeNext:^(id x) {
        NSLog(@"%@",x);
    }];
    
    //3. 包装元组
    RACTuple *tuple = RACTuplePack(@1,@2);
    
    //4.@weakify() @strongify()用来解决循环引用
    

    RACCommand

    在开发中常用于处理事件,比如网络请求。

    // 1.创建命令
    RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
        // input:执行命令传入参数
        // Block调用:执行命令的时候就会调用
        NSLog(@"%@",input);
        return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
         // 发送数据
          [subscriber sendNext:@"执行命令产生的数据"];
            return nil;
        }];
    }];
    // 2.执行命令
    RACSignal *signal = [command execute:@1];
    // 3.订阅信号拿到信号中发送的数据。
    [signal subscribeNext:^(id x) {
        NSLog(@"%@",x);
    }];
    //这个方法也能拿到信号中发送的数据
    [command.executionSignals.switchToLatest subscribeNext:^(id x) {
        NSLog(@"%@",x);
    }];
    // 监听事件有没有完成
    [command.executing subscribeNext:^(id x) {
        if ([x boolValue] == YES) { // 当前正在执行
            NSLog(@"当前正在执行");
        }else{
            // 执行完成/没有执行
            NSLog(@"执行完成/没有执行");
        }
    }];
    

    RAC中的映射

    flattenMap用于信号中的信号

     // 创建信号
    RACSubject *subject = [RACSubject subject];
    // 绑定信号
    RACSignal *bindSignal = [subject flattenMap:^RACStream *(id value) {
        // block:只要源信号发送内容就会调用
        // value:就是源信号发送内容
        value = [NSString stringWithFormat:@"xmg:%@",value];
        // 返回信号用来包装成修改内容值
        return [RACReturnSignal return:value];
    }];
    // flattenMap中返回的是什么信号,订阅的就是什么信号
    // 订阅信号
    [bindSignal subscribeNext:^(id x) {
        NSLog(@"%@",x);
    }];
    // 发送数据
    [subject sendNext:@"123"];
    

    map

     // 创建信号
    RACSubject *subject = [RACSubject subject];
    // 绑定信号
    RACSignal *bindSignal = [subject map:^id(id value) {
        // 返回的类型,就是你需要映射的值
        return [NSString stringWithFormat:@"haha:%@",value];
    }];
    // 订阅绑定信号
    [bindSignal subscribeNext:^(id x) {
        NSLog(@"%@",x);
    }];
    [subject sendNext:@"1"];
    

    RAC信号组合

    concat

    // 创建信号A
    RACSignal *siganlA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        // 发送请求
        NSLog(@"发送上部分请求");
        // 发送信号
        [subscriber sendNext:@"上部分数据"];
        [subscriber sendCompleted];
        return nil;
    }];
    RACSignal *siganlB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        // 发送请求
        NSLog(@"发送下部分请求");
        // 发送信号
        [subscriber sendNext:@"下部分数据"];
        return nil;
    }];
    // concat:按顺序去连接
    // 注意:concat,第一个信号必须要调用sendCompleted
    // 创建组合信号
    RACSignal *concatSignal = [siganlA concat:siganlB];
    // 订阅组合信号
    [concatSignal subscribeNext:^(id x) {
        // 既能拿到A信号的值,又能拿到B信号的值
        NSLog(@"%@",x);
    }];
    

    combineLatest

    // 组合    
    // reduceBlock参数:根组合的信号有关,一一对应
    RACSignal *comineSiganl = [RACSignal combineLatest:@[_accountFiled.rac_textSignal,_pwdField.rac_textSignal] reduce:^id(NSString *account,NSString *pwd){
        // block:只要源信号发送内容就会调用,组合成新一个值
        NSLog(@"%@ %@",account,pwd);
        // 聚合的值就是组合信号的内容
        return @(account.length && pwd.length);
    }];
     // 订阅组合信号
    RAC(_loginBtn,enabled) = comineSiganl;
    

    RAC过滤

    filte过滤信号

    // 只有当我们文本框的内容长度大于5,才想要获取文本框的内容
    [[_textField.rac_textSignal filter:^BOOL(id value) {
        // value:源信号的内容
        return  [value length] > 5;
        // 返回值,就是过滤条件,只有满足这个条件,才能能获取到内容
    }] subscribeNext:^(id x) {
        NSLog(@"%@",x);
    }];
    

    ignore:忽略一些值

     // 1.创建信号
    RACSubject *subject = [RACSubject subject];
    // 2.忽略一些
    RACSignal *ignoreSignal = [subject ignoreValues];
    // 3.订阅信号
    [ignoreSignal subscribeNext:^(id x) {
        NSLog(@"%@",x);
    }];
    // 4.发送数据
    [subject sendNext:@"13"];
    

    skip;跳跃几个值

     // 1.创建信号
    RACSubject *subject = [RACSubject subject];
    [[subject skip:2] subscribeNext:^(id x) { 
        NSLog(@"%@",x);
    }];
    [subject sendNext:@"1"];
    [subject sendNext:@"2"];
    [subject sendNext:@"3"];

    相关文章

      网友评论

        本文标题:RAC基本用法

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