学习响应式编程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<NSKeyValueChangeKey,id> *)change context:(void *)context
{
    NSLog(@"观察到了");
}
-(void)touchesBegan:(NSSet<UITouch *> *)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<UITouch *> *)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+maxFloatLength<x.length) {
                    //输入位数超出精确度限制,进行截取
                    self.numTextF.text=[x substringToIndex:pointRange.location+maxFloatLength+1];
                }
            }
            else{
                if (x.length>maxIntegerLength) {
                    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];
    }];

未完待续...

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容