zoukankan      html  css  js  c++  java
  • ReactiveCocoa 初学者使用

    skip 跳过几个信号,不接受

    filter :过滤

    ignore:忽略某一个值

    take:从开始一共取N次的信号

    ignoreValues 这个比较极端,忽略所有值,只关心Signal结束,也就是只取Comletion和Error两个消息,中间所有值都丢弃

    takeUntilBlock 对于每个next值,运行block,当block返回YES时停止取值

    takeLast 取最后N次的信号,前提条件,订阅者必须调用完成,因为只有完成,就知道总共有多少信号

    skipUntilBlock 同理,一直跳,直到block为YES

    skipWhileBlock  一直跳,直到block为NO

    1.信号量

       _curTag=@"error";
        
        @weakify(self)
        //完整的创建RACSignal 包含三部分sendError(不一定要有) sendNext(可多个)  sendCompleted(不一定要有)
        //RACSubscriber:表示订阅者的意思,用于发送信号,这是一个协议,不是一个类,只要遵守这个协议,并且实现方法才能成为订阅者。通过create创建的信号,都有一个订阅者,帮助他发送数据
        RACSignal *signal=[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            @strongify(self)
            NSError *error;
            if ([self.curTag isEqualToString:@"error1"]) {
                error=[[NSError alloc]initWithDomain:@"myError" code:2001 userInfo:nil];
                [subscriber sendError:error];
            }
            else
            {
                [subscriber sendNext:@"1"];
                [subscriber sendNext:@"3"];
                [subscriber sendNext:@"5"];
                [subscriber sendCompleted];
            }
            return [RACDisposable disposableWithBlock:^{
                NSLog(@"执行清理");
                //RACDisposable:用于取消订阅或者清理资源,当信号发送完成或者发送错误的时候,就会自动触发它
                //使用场景:不想监听某个信号时,可以通过它主动取消订阅信号
            }];
        }];
        
        [signal subscribeNext:^(id x) {
            NSLog(@"当前的值为:%@",x);
        }];
        
    
        [signal subscribeError:^(NSError *error) {
            NSLog(@"当前出现错误%@",error);
        }];
        
        [signal subscribeNext:^(id x) {
            NSLog(@"2当前的值为:%@",x);
        }];
        
        //输出
    //    执行清理
    //    当前出现错误Error Domain=myError Code=2001 "(null)"
    //    执行清理
    //    执行清理
    
     //创建信号
        RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            //发送信号
            [subscriber sendNext:@"我是好人"];
            [subscriber sendCompleted];
            return nil;
        }];
        
        //订阅信号
        [signal subscribeNext:^(id x) {
            NSLog(@"%@",x);
        }];
        
    

     上面的代码合成:

     //创建信号
        [[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            //发送信号
            [subscriber sendNext:@"我是好人"];
            [subscriber sendCompleted];
            return nil;
        }] subscribeNext:^(id x) {
             NSLog(@"%@",x);
        }];
    

     运行结果

    2.数组字典使用:

     NSArray *array = @[@1,@2,@3];
        
        [array.rac_sequence.signal subscribeNext:^(id x) {
            //1
            //2
            //3
            NSLog(@"%@",x);
        }];
    
     NSDictionary *dict = @{@"name":@"张三",@"age":@"20",@"sex":@"男"};
        
        [dict.rac_sequence.signal subscribeNext:^(id x) {
            
            // 解包元组,会把元组的值,按顺序给参数里面的变量赋值
            // RACTupleUnpack这是个宏,后面会介绍
            
    //        name---张三
    //        age---20
    //        sex---男
            RACTupleUnpack(NSString *key,NSString *value) = x;
            
            NSLog(@"%@---%@",key,value);
            
            //相当与
            //        NSString *key = x[0];
            //        NSString *value = x[1];
        }];
    
     //把NSArray通过rac_sequence方法生成RAC中的Sequence  获取该Sequence对象的信号量
        RACSequence *sequence = [@[@"you", @"are", @"beautiful"] rac_sequence];
        
        //调用Signal的Map方法,使每个元素的首字母大写
        RACSignal *signal =  sequence.signal;
        
        RACSignal *capitalizedSignal = [signal map:^id(NSString * value) {
            return [value capitalizedString];
        }];
        
        
    //    通过subscribNext方法对其进行遍历输出
        [signal subscribeNext:^(NSString * x) {
            NSLog(@"signal --- %@", x);
        }];
        
        [capitalizedSignal subscribeNext:^(NSString * x) {
            NSLog(@"capitalizedSignal --- %@", x);
        }];
    

     运行结果:

    合并信号:

     RACSubject *letters = [RACSubject subject];
        RACSubject *numbers = [RACSubject subject];
        RACSubject *chinese = [RACSubject subject];
        
        [[RACSignal
          merge:@[letters, numbers, chinese]]
         subscribeNext:^(id x) {
             NSLog(@"merge:%@", x);
         }];
        
        [letters sendNext:@"AAA"];
        [numbers sendNext:@"666"];
        [chinese sendNext:@"你好!"];
        
        //AAA    666   你好!
    

    组合信号:

    RACSubject *letters = [RACSubject subject];
        RACSubject *numbers = [RACSubject subject];
        
        [[RACSignal
          combineLatest:@[letters, numbers]
          reduce:^(NSString *letter, NSString *number){
    //          reduce块中是合并规则:把numbers中的值拼接到letters信号量中的值后边。
              return [letter stringByAppendingString:number];
          }]
         subscribeNext:^(NSString * x) {
             NSLog(@"%@", x);
         }];
        
        
        [letters sendNext:@"A"];
        [letters sendNext:@"B"];
        [numbers sendNext:@"1"];
        [letters sendNext:@"C"];
        [numbers sendNext:@"2"];
        
        
        //B1 C1 C2
    

    信号开关:

     //创建3个自定义信号
        RACSubject *google = [RACSubject subject];
        RACSubject *baidu = [RACSubject subject];
        
        
        
        
        
        RACSubject *signalOfSignal = [RACSubject subject];
        
        //获取开关信号
        RACSignal *switchSignal = [signalOfSignal switchToLatest];
        
        
        
     
        
        //对通过开关的信号量进行操作
        [[switchSignal  map:^id(NSString * value) {
            return [@"https//www." stringByAppendingFormat:@"%@", value];
        }] subscribeNext:^(NSString * x) {
            NSLog(@"%@", x);
        }];
        
        
        //通过开关打开baidu
        [signalOfSignal sendNext:baidu];
        [baidu sendNext:@"baidu.com"];
        [google sendNext:@"google.com"];
        
        //通过开关打开google
        [signalOfSignal sendNext:google];
        [baidu sendNext:@"baidu.com/"];
        [google sendNext:@"google.com/"];
    

    代理:

    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"RAC" message:@"RAC TEST" delegate:self cancelButtonTitle:@"cancel" otherButtonTitles:@"other", nil];
        [[self rac_signalForSelector:@selector(alertView:clickedButtonAtIndex:) fromProtocol:@protocol(UIAlertViewDelegate)] subscribeNext:^(RACTuple *tuple) {
            NSLog(@"%@",tuple.first);
            NSLog(@"%@",tuple.second);
            NSLog(@"%@",tuple.third);
        }];
        [alertView show];
    

    字符串信号判断:

    _input1 =  @"2w435768";
        
        [[RACObserve(self, input1)
          filter:^(NSString* value){
              if ([value hasPrefix:@"2"]) {
                  return YES;
              } else {
                  return NO;
              }
          }]
         subscribeNext:^(NSString* x){
                      NSLog(@"%@",x);
         }];

    监听textfield:

     [[self.input.rac_textSignal
          filter:^(NSString *str) {
              if ([str hasPrefix:@"3545"]) {
                  return YES;
              } else {
                  return NO;
              }
          }]
         subscribeNext:^(NSString *str) {
             NSLog(@"%@",str);
             
         }];
    

    Button是否可用:

     self.isConnected = [NSNumber numberWithBool:true];
    
        RAC(self.loginBtn,enabled) = [RACSignal
                                       combineLatest:@[self.name.rac_textSignal,
                                                       self.password.rac_textSignal,
                                                       RACObserve(self, isConnected)
                                                       ]
                                       reduce:^(NSString *price, NSString *name, NSNumber *connect){
                                           return @(price.length > 0 && name.length > 0 && [connect boolValue]);
                                       }
                                       ];
    

    满足条件发送:

           [[RACSignal
          combineLatest:@[self.price.rac_textSignal,
                          self.name.rac_textSignal,
                          RACObserve(self, isConnected)
                          ]
          reduce:^(NSString *price, NSString *name, NSNumber *connect){
              return @(price.length > 0 && name.length > 0 && ![connect boolValue]);
          }]
         subscribeNext:^(NSNumber *res){
             if ([res boolValue]) {
                 NSLog(@"XXXXX send request");
             }
         }];
    

    RACCommand使用

     /**
         
         // 1.signalBlock必须要返回一个信号,不能传nil.
         // 2.如果不想要传递信号,直接创建空的信号[RACSignal empty];
         // 3.RACCommand中信号如果数据传递完,必须调用[subscriber sendCompleted],这时命令才会执行完毕,否则永远处于执行中。
         
         // 三、RACCommand设计思想:内部signalBlock为什么要返回一个信号,这个信号有什么用。
         // 1.在RAC开发中,通常会把网络请求封装到RACCommand,直接执行某个RACCommand就能发送请求。
         // 2.当RACCommand内部请求到数据的时候,需要把请求的数据传递给外界,这时候就需要通过signalBlock返回的信号传递了。
         
         // 四、如何拿到RACCommand中返回信号发出的数据。
         // 1.RACCommand有个执行信号源executionSignals,这个是signal of signals(信号的信号),意思是信号发出的数据是信号,不是普通的类型。
         // 2.订阅executionSignals就能拿到RACCommand中返回的信号,然后订阅signalBlock返回的信号,就能获取发出的值。
         
         
         
         
         */
        //1创建命令
        RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
            //命令内部传递的参数
            NSLog(@"input===%@",input);
            
            //2.返回一个信号,可以返回一个空信号 [RACSignal empty];
            return [RACSignal createSignal:^RACDisposable *(id subscriber) {
                
                NSLog(@"发送数据");
                //发送信号
                [subscriber sendNext:@"22"];
                
                // 注意:数据传递完,最好调用sendCompleted,这时命令才执行完毕。
                
                [subscriber sendCompleted];
                
                return nil;
            }];
        }];
        
        //强引用
        __command = command;
        
    //    拿到返回信号方式二:
    //    command.executionSignals信号中的信号 switchToLatest转化为信号
        [command.executionSignals.switchToLatest subscribeNext:^(id x) {
            NSLog(@"拿到信号的方式二%@",x);
        }];
        
        //拿到返回信号方式一:
        RACSignal *signal =  [command execute:@"11"];
        
        [signal subscribeNext:^(id x) {
            NSLog(@"拿到信号的方式一%@",x);
        }];
        
        //3.执行命令
        [command execute:@"11"];
        
        //监听命令是否执行完毕
        [command.executing subscribeNext:^(id x) {
            
            if ([x boolValue] == YES) {
                
                NSLog(@"命令正在执行");
            }
            else {
                
                NSLog(@"命令完成/没有执行");
            }
        }];
     
    //    input===11
    //    命令完成/没有执行
    //    命令正在执行
    //   发送数据
    //   拿到信号的方式一22
    //   拿到信号的方式二22
    //    令完成/没有执行
    

    通知:

    首先,在某个页面中我们需要发出通知,这里就是最基本的通知的写法。发送名为postdata的通知并传送一个数组dataArray。
    
    NSMutableArray *dataArray = [[NSMutableArray alloc] initWithObjects:@"1", @"2", @"3", nil];
    [[NSNotificationCenter defaultCenter] postNotificationName:@"postData" object:dataArray];
    而在接受的页面我们需要增加观察者并接受数组,这时我们的RAC就派上用场了。
    
    [[[NSNotificationCenter defaultCenter] rac_addObserverForName:@"postData" object:nil] subscribeNext:^(NSNotification *notification) {
        NSLog(@"%@", notification.name);
        NSLog(@"%@", notification.object);
    }];
    

    kvo:

    UIScrollView *scrolView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 200, 400)];
    scrolView.contentSize = CGSizeMake(200, 800);
    scrolView.backgroundColor = [UIColor greenColor];
    [self.view addSubview:scrolView];
    [RACObserve(scrolView, contentOffset) subscribeNext:^(id x) {
        NSLog(@"success");
    }];
    
    
  • 相关阅读:
    IOS-Storyboard全解析-第一部分
    IOS-Socket
    IOS-XMPP
    IOS-源代码管理工具(Git)
    IOS-源代码管理工具(SVN)
    python环境配置
    【移动开发】Android中WIFI开发总结(二)
    【移动开发】Android中WIFI开发总结(一)
    Android 连接Wifi和创建Wifi热点 demo
    Android 判断用户2G/3G/4G移动数据网络
  • 原文地址:https://www.cnblogs.com/hualuoshuijia/p/7228638.html
Copyright © 2011-2022 走看看