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");
}];

 

posted @ 2017-07-24 14:25  新年新气象  阅读(175)  评论(0编辑  收藏  举报