学习响应式编程ReactiveCocoa

我们平常所常用到的响应式编程有哪些:代理,通知,KVO,Block回调,Target,监听事件等
通过RAC我们可以更加简单的实现事件的方法,降低了代码的耦合度,更方便管理
RAC的优点:减少代码量,可灵活使用

RAC常用的几种用法:

KVO、textFiled、button - taget - event、delegate、通知、代替某个方法

RAC常用的高级用法:

过滤:filter、ignore、distinctUntilChanged、take、takeLast、takeUntil、takeWhileBlock、skip、switchToLatest
秩序:doNext、 docompleted
时间:retry、interval、delay
重复:retry、replay、throttle
其他方法:startWith

RAC的重要概念:

RACSignal、RACSubscriber、RACSubject

集成:

Objective-C:pod 'ReactiveCocoa', '2.1.8'
Swift:https://github.com/ReactiveCocoa

RAC: 信号 面向信号开发!!

1.创建信号!!

RACSubject *subject = [RACSubject subject];

2.谁对信号感兴趣,谁订阅信号(订阅者)

[subject subscribeNext:^(id x) {
        NSLog(@"%@",x);//Hello RAC!!
    }];

3.我发送信号

[subject sendNext:@"Hello RAC!!"];

代理

常用方法

1.定义一个方法
2.定义协议方法
3.定义一个代理属性(遵守这个协议)
4.当发生一些事情,我看看代理属性有没有值
5.看看代理有没有响应我的方法!

使用代理

1.设置代理
2.遵守协议
3.实现方法

//HKView页面
UIButton *btn = [[UIButton alloc]initWithFrame:CGRectMake(100, 100, 100, 100)];
    [btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];

-(void)btnClick:(UIButton *)send
{
    点击事件的处理过程
}

RAC方法

    [[self.HkView rac_signalForSelector:@selector(btnClick:)] subscribeNext:^(id x) {
        点击事件的处理过程
    }];

代理传值

//传值页面
UIButton *btn = [[UIButton alloc]initWithFrame:CGRectMake(100, 100, 100, 100)];
    [btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
-(void)btnClick:(UIButton *)send
{
    [self sendContent:@"今天真开心!!"];
}

-(void)sendContent:(id)objc
{
    //可以什么都不做
}
//数据显示和处理页面
[[self.HkView rac_signalForSelector:@selector(sendContent:)]subscribeNext:^(id x) {
        NSLog(@"%@",x);//今天真开心
    }];

KVO

监听view的frame的变化

平时写法

[self.hKView addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionNew context:nil];
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    NSLog(@"观察到了");
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    self.hKView.frame = CGRectMake(100, 100, 50, 50);
}

其他实例
// RACObserve(TARGET, KEYPATH):KVO,监听某个对象的属性,返回的是信号。

第一步:[self NotificationCenter];

   第二步: [RACObserve(self.tabelView1, backgroundColor) subscribeNext:^(id  _Nullable x) {
        NSLog(@"self.view换了新背景颜色:%@",x);
    }];


第三步:-(void)NotificationCenter
{
    self.tabelView1.backgroundColor = [UIColor orangeColor];
}
    [RACObserve(_tabelView1, contentOffset)subscribeNext:^(id x) {
        //监听scrollview的滑动
        NSLog(@"success:%@",x);
    }];
    //五秒后执行一次,延时执行
    [[RACScheduler mainThreadScheduler]afterDelay:5 schedule:^{
       
        NSLog(@"五秒后执行一次");
        self.tabelView1.backgroundColor = [UIColor redColor];
        
    }];
    //每隔两秒执行一次
    //这里要加takeUntil条件限制一下否则当控制器pop后依旧会执行
    [[[RACSignal interval:2 onScheduler:[RACScheduler mainThreadScheduler]] takeUntil:self.rac_willDeallocSignal ] subscribeNext:^(id x) {

        NSLog(@"每两秒执行一次");

    }];
}

RAC写法

用来给某个对象的某个属性绑定信号,只要产生信号内容,就会将内容赋值给属性
//方法1:
[[self.hKView rac_valuesAndChangesForKeyPath:@"frame" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld observer:nil ]subscribeNext:^(id  _Nullable x) {
        NSLog(@"RAC观察到了");
    }];
//方法2:
[[self.hKView rac_valuesForKeyPath:@"frame" observer:self]subscribeNext:^(id  _Nullable x) {
        NSLog(@"RAC观察到了");
    }];
//方法3:
[RACObserve(self.hKView, frame) subscribeNext:^(id  _Nullable x) {
        NSLog(@"RAC观察到了");
    }];
最大的好处是:当需要观察某个对象的某些属性时,简化了代码,使代码更好维护和阅读

监听事件

常用写法

UIButton *btn = [[UIButton alloc]initWithFrame:CGRectMake(100, 100, 100, 100)];
    [btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];

-(void)btnClick:(UIButton *)send
{
   NSLog(@"今天真开心!!");
}

RAC写法

//监听按钮的点击事件
[[btn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(id x) {
        NSLog(@"今天真开心!!");
    }];

通知

RAC通知传值

//RAC通知
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
//    在某个页面中我们需要发出通知,发送名为postdata的通知并传送一个数组dataArray
    NSMutableArray *dataArray = [[NSMutableArray alloc] initWithObjects:@"1", @"2", @"3", nil];
    [[NSNotificationCenter defaultCenter] postNotificationName:@"postData" object:dataArray];
}
//调用键盘的通知
[[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardWillShowNotification object:nil] subscribeNext:^(id x) {
        //可处理键盘弹出时页面布局问题等
    }];

UITextFiled

监听textFiled的输入

文本框实时的监听

[self.numTextF.rac_textSignal subscribeNext:^(NSString *x) {
          NSLog(@"文本框输入的内容:%@" ,x);
}];
[self.nameTextF.rac_newTextChannel subscribeNext:^(id  _Nullable x) {
        NSLog(@"输出什么:%@",x);
    }];
    [[self.nameTextF rac_inputTextSignal]subscribeNext:^(id x) {
        
        NSLog(@"打印2:%@",x);
        
    }];
//RAC的实时赋值
RAC(_labe1, text) = _numTextF.rac_textSignal;

textFiled数字输入监听

[self.numTextF.rac_textSignal subscribeNext:^(NSString *x) {
        
        static NSInteger const maxIntegerLength=8;//最大整数位
        static NSInteger const maxFloatLength=2;//最大精确到小数位
        
        if (x.length) {
            //第一个字符处理
            //第一个字符为0,且长度>1时
            if ([[x substringWithRange:NSMakeRange(0, 1)] isEqualToString:@"0"]) {
                if (x.length>1) {
                    if ([[x substringWithRange:NSMakeRange(1, 1)] isEqualToString:@"0"]) {
                        //如果第二个字符还是0,即"00",则无效,改为"0"
                        self.numTextF.text=@"0";
                    }else if (![[x substringWithRange:NSMakeRange(1, 1)] isEqualToString:@"."]){
                        //如果第二个字符不是".",比如"03",清除首位的"0"
                        self.numTextF.text=[x substringFromIndex:1];
                    }
                }
            }
            //第一个字符为"."时,改为"0."
            else if ([[x substringWithRange:NSMakeRange(0, 1)] isEqualToString:@"."]){
                self.numTextF.text=@"0.";
            }
            
            //2个以上字符的处理
            NSRange pointRange = [x rangeOfString:@"."];
            NSRange pointsRange = [x rangeOfString:@".."];
            if (pointsRange.length>0) {
                //含有2个小数点
                self.numTextF.text=[x substringToIndex:x.length-1];
            }
            else if (pointRange.length>0){
                //含有1个小数点时,并且已经输入了数字,则不能再次输入小数点
                if ((pointRange.location!=x.length-1) && ([[x substringFromIndex:x.length-1]isEqualToString:@"."])) {
                    self.numTextF.text=[x substringToIndex:x.length-1];
                }
                if (pointRange.location+maxFloatLengthmaxIntegerLength) {
                    self.numTextF.text=[x substringToIndex:maxIntegerLength];
                }
            }
            
        }
        
    }];

监听输入字体个数的简单处理

//监听输入字体个数
    NSInteger maxLenght = 10;
    [[self.nameTextF.rac_textSignal filter:^BOOL(NSString * _Nullable value) {
        return value.length > maxLenght;
    }] subscribeNext:^(NSString * _Nullable x) {
//        NSLog(@"最多输入10个文字");
        self.nameTextF.text = [self.nameTextF.text substringToIndex:maxLenght];
    }];

未完待续...

你可能感兴趣的:(学习响应式编程ReactiveCocoa)