无标题文章

1.ReactiveCocoa简介

ReactiveCocoa(简称为RAC),是由Github开源的一个应用于iOS和OS开发的新框架,Cocoa是苹果整套框架的简称,因此很多苹果框架喜欢以Cocoa结尾。

2.ReactiveCocoa作用

在我们iOS开发过程中,当某些事件响应的时候,需要处理某些业务逻辑,这些事件都用不同的方式来处理。
比如按钮的点击使用action,ScrollView滚动使用delegate,属性值改变使用KVO等系统提供的方式。
其实这些事件,都可以通过RAC处理
ReactiveCocoa为事件提供了很多处理方法,而且利用RAC处理事件很方便,可以把要处理的事情,和监听的事情的代码放在一起,这样非常方便我们管理,就不需要跳到对应的方法里。非常符合我们开发中高聚合,低耦合的思想

在RAC中最核心的类RACSiganl

RACSubscriber:表示订阅者的意思,用于发送信号,这是一个协议,不是一个类,只要遵守这个协议,并且实现方法才能成为订阅者。通过create创建的信号,都有一个订阅者,帮助他发送数据

  //RACSignal信号使用步骤:1:创建信号  2:订阅信号  3: 发送信号
    
    //1:创建信号
    RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        
        //didSubscribe调用:只有被订阅了,才调用
        //didSubscribe作用:发送数据
        //3:发送信号
        
        [subscriber sendNext:@1];
        return  nil;
    }];
    
    //2:订阅信号
    [signal subscribeNext:^(id x) {
        
        //nextBlock调用:只有发送数据了才会调用
        //nextBlock作用:接受数据,展示UI
        NSLog(@"%@",x);
    }];

```

```RACDisposable```: 用于取消订阅或者清理资源,当信号发送完成或者发送错误的时候,就会自动触发它。
   --不想监听某个信号时,可以通过它主动取消订阅信号。
```objc 
-(void)racWithSignalDisposable{
    
    //1:创建信号
    RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        
        _subscriber = subscriber;
        //3发送信号
        [subscriber sendNext:@1];
        
        return [RACDisposable disposableWithBlock:^{
            
            NSLog(@"取消订阅");
        }];
    }];
    
    //2:订阅信号
    
    RACDisposable *disposable = [signal subscribeNext:^(id x) {
        
        NSLog(@"%@",x);
    }];
    
    //主要订阅者在就不会取消订阅者
    [disposable dispose];
}

```


```RACSubject:RACSubject:``` 信号提供者,自己可以充当信号,又能发送信号。

使用场景:通常用来代替代理,有了它,就不必要定义代理了。
```objc
-(RACSubject *)subject{
    
    if (_subject == nil) {
        
        _subject = [RACSubject subject];
    }
    return _subject;
}
-(IBAction)clickBtn:(UIButton *)btn{

    [self.subject sendNext:@1];
}
-(void)racWithDelegate{
    
    //订阅
    [_redView.subject subscribeNext:^(id x) {
        
        NSLog(@"控制器做了一件事情%@",x);
    }];
}

```
```RACTuple```: 元组类,类似NSArray,用来包装值.
```objc 
-(void)racWtihTuple{

    //rac集合
    RACTuple *tuple = [RACTuple tupleWithObjectsFromArray:@[@"123",@"234",@1]];
    
    //取出rac集合中的第0个元素
    NSString *str =  tuple[0];
    
    NSLog(@"%@",str);

}

```
```RACSequence``` :RAC中的集合类,用于代替NSArray,NSDictionary,可以使用它来快速遍历数组和字典。
```objc 
-(void)racWithAarray{
    
    //rac遍历数组
    
    //创建一个数组
    NSArray *arry = @[@"123",@"321",@"111"];
    
    //把数组转变为一个集合
    RACSequence *sequence = arry.rac_sequence;
    
    //把集合转换为一个信号
    RACSignal *singnal = sequence.signal;
    
    //使用信号订阅信息
    [singnal subscribeNext:^(id x) {
        
        NSLog(@"%@",x);
    }];
    
    [arry.rac_sequence.signal subscribeNext:^(id x) {
        
        NSLog(@"%@",x);
    }];

}

```

实例:
```objc 
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    
    self.person.userName = [NSString stringWithFormat:@"zhangsan---%u",arc4random_uniform(100)];
    
}
//rac实现kvo
-(void)racWithKvo{
    
    [RACObserve(self.person, userName) subscribeNext:^(id x) {
       
        self.nameLabel.text = x;
    }];
    
}

  [_accountTextFiled.rac_textSignal subscribeNext:^(id x) {
       
        self.nameLabel.text = x;
    }];
  
```
#多个输入文件作为信号源 
多用于登陆等业务需求
```objc 
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px 'PingFang SC'; color: #4cbf57}p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #ffffff}p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #ffffff; min-height: 13.0px}p.p4 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #93c86a}p.p5 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #4cbf57}span.s1 {font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures}span.s2 {font-variant-ligatures: no-common-ligatures}span.s3 {font-variant-ligatures: no-common-ligatures; color: #c2349b}span.s4 {font-variant-ligatures: no-common-ligatures; color: #ffffff}span.s5 {font-variant-ligatures: no-common-ligatures; color: #00afca}span.s6 {font-variant-ligatures: no-common-ligatures; color: #8b84cf}span.s7 {font: 11.0px 'PingFang SC'; font-variant-ligatures: no-common-ligatures}span.s8 {font-variant-ligatures: no-common-ligatures; color: #93c86a}span.s9 {font-variant-ligatures: no-common-ligatures; color: #e44448}

//多个文本框输入信号组合使用
-(void)racTextFiledsDemo{
    
    RACSignal *nameSignal = [self.nameTextFiled rac_textSignal];
    RACSignal *pwdSignal = [self.pwdTextFiled rac_textSignal];
    
    NSArray *signals = @[nameSignal,pwdSignal];
    
    //订阅信号
    [[RACSignal combineLatest:signals]subscribeNext:^(RACTuple *x) {
       
        NSString *name = x.first;
        NSString *pawd = x.second;
        NSLog(@"%@%@",x,name);
        
        if (name.length>0 && pawd.length>0) {
            
            self.photoImageView.image = [UIImage imageNamed:@"Demo"];
        }else if(name.length >0 || pawd.length > 0){
            
            self.photoImageView.image = [UIImage imageNamed:@"Demo1"];
        }
    
    }];
    
}
```
#rac_signalForSelector的使用,代替代理(不需要传值的情况下)
```objc 

p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #4cbf57}p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #93c86a}p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #ffffff; min-height: 13.0px}p.p4 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #ffffff}span.s1 {font-variant-ligatures: no-common-ligatures; color: #ffffff}span.s2 {font-variant-ligatures: no-common-ligatures}span.s3 {font: 11.0px 'PingFang SC'; font-variant-ligatures: no-common-ligatures}span.s4 {font-variant-ligatures: no-common-ligatures; color: #c2349b}span.s5 {font-variant-ligatures: no-common-ligatures; color: #00afca}span.s6 {font-variant-ligatures: no-common-ligatures; color: #e44448}span.s7 {font-variant-ligatures: no-common-ligatures; color: #93c86a}

  //rac_signalForSelector:监听某对象有没有调用某方法
    [[self.readView rac_signalForSelector:@selector(clickBtn:)] subscribeNext:^(id x) {
       
        NSLog(@"clickBtn");
    }];
    [[self rac_signalForSelector:@selector(didReceiveMemoryWarning)] subscribeNext:^(id x) {
        
        NSLog(@"clickBtn");
    }];
    
```

```objc 
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #ffffff}p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #ffffff; min-height: 13.0px}span.s1 {font-variant-ligatures: no-common-ligatures}span.s2 {font-variant-ligatures: no-common-ligatures; color: #c2349b}

@weakify(self)

    [RACObserve(self.person, name) subscribeNext:^(id x) {
        
        @strongify(self)
```



#全部代码
```objc 
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #ffffff}p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #ffffff; min-height: 13.0px}p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #e44448}p.p4 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #4cbf57}p.p5 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #93c86a}p.p6 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px 'PingFang SC'; color: #4cbf57}p.p7 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #00afca}span.s1 {font-variant-ligatures: no-common-ligatures}span.s2 {font-variant-ligatures: no-common-ligatures; color: #c2349b}span.s3 {font-variant-ligatures: no-common-ligatures; color: #ffffff}span.s4 {font-variant-ligatures: no-common-ligatures; color: #00afca}span.s5 {font: 11.0px 'PingFang SC'; font-variant-ligatures: no-common-ligatures}span.s6 {font-variant-ligatures: no-common-ligatures; color: #e44448}span.s7 {font-variant-ligatures: no-common-ligatures; color: #93c86a}span.s8 {font: 11.0px Menlo; font-variant-ligatures: no-common-ligatures}span.s9 {font-variant-ligatures: no-common-ligatures; color: #8b84cf}span.s10 {font: 11.0px 'PingFang SC'; font-variant-ligatures: no-common-ligatures; color: #e44448}span.s11 {font-variant-ligatures: no-common-ligatures; color: #d28f5a}span.s12 {font-variant-ligatures: no-common-ligatures; color: #4cbf57}span.s13 {font: 11.0px 'PingFang SC'; font-variant-ligatures: no-common-ligatures; color: #4cbf57}

}
-(void)dealloc{
    
    NSLog(@"viewController dealloc");
}
//rac代替代理
-(void)racWithDelegate{
    
//    1:rac的subject  2:rac的select
    
    //rac_signalForSelector:监听某对象有没有调用某方法
    [[self.readView rac_signalForSelector:@selector(clickBtn:)] subscribeNext:^(id x) {
       
        NSLog(@"clickBtn");
    }];
    [[self rac_signalForSelector:@selector(didReceiveMemoryWarning)] subscribeNext:^(id x) {
        
        NSLog(@"clickBtn");
    }];
    
}
//多个文本框输入信号组合使用
-(void)racTextFiledsDemo{
    
    RACSignal *nameSignal = [self.nameTextFiled rac_textSignal];
    RACSignal *pwdSignal = [self.pwdTextFiled rac_textSignal];
    
    NSArray *signals = @[nameSignal,pwdSignal];
    
    //订阅信号
    [[RACSignal combineLatest:signals]subscribeNext:^(RACTuple *x) {
       
        NSString *name = x.first;
        NSString *pawd = x.second;
        NSLog(@"%@%@",x,name);
        
        if (name.length>0 && pawd.length>0) {
            
            self.photoImageView.image = [UIImage imageNamed:@"Demo"];
        }else if(name.length >0 || pawd.length > 0){
            
            self.photoImageView.image = [UIImage imageNamed:@"Demo1"];
        }
    
    }];
    
}
//rac及时刷新UI
-(void)racWithUI{
    
    [_nameTextFiled.rac_textSignal subscribeNext:^(id x) {
        
        self.nameLabel.text = x;
    }];
    
}

//rRAC中的集合类,用于代替NSArray,NSDictionary,可以使用它来快速遍历数组和字典。
-(void)racWithSeq{
    
    NSArray *array = @[@"7",@"3",@"4",@"5"];
    
//    //把数组转为一个集合
//    RACSequence *sequence = array.rac_sequence;
//    
//    //把集合转为一个信号
//    RACSignal *signal = sequence.signal;
//    
//    //使用订阅者订阅信号
//    [signal subscribeNext:^(id x) {
//       
//        NSLog(@"%@",x);
//    }];
    
    [array.rac_sequence.signal subscribeNext:^(id x) {
       
        NSLog(@"%@",x);
    }];
}

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    
    self.person.name = [NSString stringWithFormat:@"liuYAHUA---%u",arc4random_uniform(100)];
}
//rac中的kvo
-(void)racWithKvo{
    
    @weakify(self)
    //观察person的name属性
    [RACObserve(self.person, name) subscribeNext:^(id x) {
       
        @strongify(self)
        self.nameLabel.text = x;
    }];
    
    
    
}

//rac中订阅者的取消
-(void)racWithSignalDisposable{
    
    //rac中最核心的就是信号  1:创建信号  2:订阅信号  3:发送信号
    
    //1:创建信号
    RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        
        
        //didSubscribe调用:只有被订阅了,才会调用
        //didSubscribe作用:发送数据
        
        _subscriber = subscriber;
        
        //3:发送信号
        [subscriber sendNext:@"刘亚华"];
        
        return [RACDisposable disposableWithBlock:^{
            
            NSLog(@"刘亚华被取消了");
        }];
    }];
    
    //2:订阅信号
    RACDisposable *disposable =  [signal subscribeNext:^(id x) {
        
        //nextBlock调用:只有发送了数据才会调用
        //nextBlock作用:接受数据,展示UI
        
        NSLog(@"%@",x);
    }];
    
    //取消
    [disposable dispose];
    
    
}

-(void)racWithSignal{

    //rac中最核心的就是信号  1:创建信号  2:订阅信号  3:发送信号
    
    //1:创建信号
    RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        
        
        //didSubscribe调用:只有被订阅了,才会调用
        //didSubscribe作用:发送数据
        
        //3:发送信号
        [subscriber sendNext:@"刘亚华"];
        
        return nil;
    }];
    
    //2:订阅信号
    [signal subscribeNext:^(id x) {
        
        //nextBlock调用:只有发送了数据才会调用
        //nextBlock作用:接受数据,展示UI
        
        NSLog(@"%@",x);
    }];
    

}  

```
#链式编程

```objc 
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #ffffff}p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #ffffff; min-height: 13.0px}span.s1 {font-variant-ligatures: no-common-ligatures}span.s2 {font-variant-ligatures: no-common-ligatures; color: #c2349b}span.s3 {font-variant-ligatures: no-common-ligatures; color: #00afca}span.s4 {font-variant-ligatures: no-common-ligatures; color: #e44448}span.s5 {font-variant-ligatures: no-common-ligatures; color: #93c86a}

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

推荐阅读更多精彩内容