ReactiveCocoa之基本使用

之前写了一篇关于ReactiveCocoa入门的文章,里面只是简单的介绍了ReactiveCocoa 的基本方法。接下来我会针对不同的方法 怎么使用做一下简单的介绍。

Tips:

cocoPods导入时 oc : pod ‘ReactiveObjC’ swift : pod ‘ReactiveCocoa’ 详细可查看官方介绍 http://reactivecocoa.io

话不多说上代码

RACSignal(信号类)

1、RAC 的核心就是RACSignal 它是一个信号类 一般需要三个步骤。

1.1 创建信号
1.2 订阅信号
1.3 发送信号

 //创建信号
    RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        /**
         RACSubscriber 是一个协议类 只有遵循这个协议才能成为订阅者
         */
        //发送信号 可以是任意类型
         [subscriber sendNext:self.dataArray];
        //信号发送成功
        [subscriber sendCompleted];
        
        return [RACDisposable disposableWithBlock:^{
        //销毁信号
            
        }];
        
    }];
    
    //订阅信号
    [signal subscribeNext:^(id  _Nullable x) {
        
        NSLog(@"接受数据---%@",x);
        
    }];

你可以这样理解 你在某宝上相中了一款商品需要预付定金 等开售的时候开始给你发货。预付定金相当于订阅信号、开售发货相当于发送信号。是不是这个道理。

2、底层原理简单分析

2.1 创建信号,首先把didSubscribe保存到信号中,还不会触发。
2.2 当信号被订阅,也就是调用signal的subscribeNext:nextBlock
2.3 subscribeNext内部会创建订阅者subscriber,并且把nextBlock保存到subscriber中。
2.4 subscribeNext内部会调用siganl的didSubscribe
2.5 signal的didSubscribe中调用[subscriber sendNext:id];
2.6 sendNext底层其实就是执行subscriber的nextBlock
点击这里可以查看RACSignal的常用用法

RACSubject

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

 RACSubject *subject = [RACSubject subject];
  [subject subscribeNext:^(id  _Nullable x) {
        
   //订阅信号
        
    }];
     //发送信号
    [subject sendNext:@"要发送的数据"];
- (RACDisposable *)subscribeNext:(void (^)(id x))nextBlock {
    NSCParameterAssert(nextBlock != NULL);
    
    RACSubscriber *o = [RACSubscriber subscriberWithNext:nextBlock error:NULL completed:NULL];
    return [self subscribe:o];
}

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

代替代理

利用RACSubject替换代理
SecondViewController.h 中 声明一个RACSubject代理

@property (nonatomic,strong)RACSubject *delegateSignal;

SecondViewController.m 中 创建一个事件传递数据

 [[self.sendButton rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {

        if (self.delegateSignal) {
            //发送信号
            [self.delegateSignal sendNext:@"代理需要传的数据"];
        }
        
    }];

跳转SecondViewController时接受代理

 [[self.signalButton rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
        
        NSLog(@"button点击事件 ---%@",x);
        SecondViewController *second = [[SecondViewController alloc] init];
        second.title = @"second";
        //设置代理信号----创建信号
        second.delegateSignal = [RACSubject subject];
        //订阅代理信号----订阅信号
        [second.delegateSignal subscribeNext:^(id x) {
            
            NSLog(@"%@",x);
            
        }];
        [self.navigationController pushViewController:second animated:YES];
        
    }];

代替通知

//注册通知
 [[[NSNotificationCenter defaultCenter] rac_addObserverForName:@"notification" object:nil] subscribeNext:^(NSNotification * notification) {
        
        NSLog(@"收到通知 notification.name=%@ notification.object=%@",notification.name,notification.object);
        
    }];
//发送通知
[[NSNotificationCenter defaultCenter] postNotificationName:@"notification" object:@"通知传值"];

代替KVO

这里 以监听UITextField的text变动为例。

#pragma mark KVO监听
    
    [[self.textField rac_valuesAndChangesForKeyPath:@"text" options:NSKeyValueObservingOptionNew observer:@""] subscribeNext:^(RACTwoTuple<id,NSDictionary *> * _Nullable x) {
        
        NSLog(@"KVO监听结果:%@",x);
        
    }];

监听某个对象的某个属性,返回的是信号 可用于搜索返回结果展示。联想一下音乐播放器搜歌。

#pragma mark 监听某个对象的某个属性,返回的是信号
    [RACObserve(self,changeString)
     subscribeNext:^(NSString* x){
         
         NSLog(@"RACObserve ----%@--",x);
         
     }];
//监听判断 
 [[RACObserve(self, changeString)filter:^BOOL(id  _Nullable value) {
        
        return [value  isEqualToString:@"开始"] ? YES : NO;
        
    }] subscribeNext:^(id  _Nullable x) {
        
        //满足上面条件才能执行
        NSLog(@"x---终于轮到我展示了");
        
    }] ;

监听事件

这里只展示开发者中常用的点击事件。以UIButton的点击事件和UILabel的手势为例。

#pragma mark button 点击事件
[[self.signalButton rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
      
      NSLog(@"button点击事件 ---%@",x);

      [self.navigationController pushViewController:second animated:YES];
      
  }];
//button事件监听的另一种方法
self.signalButton.rac_command = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id  _Nullable input) {
      
      NSLog(@"接受button事件的第二张方法");
      
      return [RACSignal empty];
  }];

#pragma mark UILabel 手势
  
  UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] init];
  
  [[tap rac_gestureSignal] subscribeNext:^(id x) {
      
      NSLog(@"label手势---%@",x);
    
  }];
[self.myLabel addGestureRecognizer:tap];

文本监测

主要针对于 UITextField、UITextView文本的监测可代替自身的代理。

 #pragma mark UITextField 文本监测
     @weakify(self)
     [self.textField.rac_textSignal subscribeNext:^(NSString *x) {
      @strongify(self)
        NSLog(@"%@",x);
        
        self.changeString = x;
        
    }];

替代遍历

1、数组遍历
 NSArray *numbers = @[@1,@2,@3,@4,@5];
    
    [numbers.rac_sequence.signal subscribeNext:^(id  _Nullable x) {
        
        NSLog(@"NSArray ---- %@",x);

    }];
2、字典遍历
 NSDictionary *dict = @{@"name":@"wang",@"age":@"18"};
    
    [dict.rac_sequence.signal subscribeNext:^(RACTuple *x) {
        
        RACTupleUnpack(NSString *key,NSString*value) = x;
        
        NSLog(@"NSDictionary ----- key=%@ value=%@",key,value);
        
    }];
3、字典转模型
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"ClassList.plist" ofType:nil];
    NSArray *dictArr = [NSArray arrayWithContentsOfFile:filePath];
    NSMutableArray *modelArray = [NSMutableArray array];
    
    [dictArr.rac_sequence.signal subscribeNext:^(id  _Nullable x) {
        
        NSLog(@"字典转模型 %@",x);
        
        classModel *model = [classModel modelObjectWithDictionary:x];
        
        [modelArray addObject:model];
        
        //        NSLog(@"名字----%@",model.name);
        
    }] ;
//简单粗暴的写法
 NSArray *flags = [[dictArr.rac_sequence map:^id(id value) {
        
        return [classModel  modelObjectWithDictionary:value];
        
    }] array];

进入相册选择照片

self.pictureButton.rac_command = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id  _Nullable input) {
        
        UIImagePickerController *pickerController = [UIImagePickerController new];
        pickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
        [pickerController.rac_imageSelectedSignal subscribeNext:^(NSDictionary * info) {
            
            UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
            
            self.myImageView.image = image;
            [pickerController dismissViewControllerAnimated:YES completion:nil];
            
        }];
        //取消
        [[pickerController.rac_delegateProxy signalForSelector:@selector(imagePickerControllerDidCancel:)] subscribeNext:^(id  _Nullable x) {
            
            [pickerController dismissViewControllerAnimated:YES completion:nil];
        }];
        //跳转
        [self presentViewController:pickerController animated:YES completion:nil];
        
        
        return [RACSignal empty];
    }];

至今已经熟悉运用的这么多。是不是比你用的要简单。先掌握熟悉运用。至于原理学习了解了再告诉大家。

参考文档

https://www.jianshu.com/p/e10e5ca413b7
https://www.jianshu.com/p/a4fefb434652
https://blog.csdn.net/jia12216/article/details/55520151
https://blog.csdn.net/wzc10101415/article/details/55051339
https://blog.csdn.net/y_csdnblog_xx/article/details/51480181
https://www.cnblogs.com/develop-SZT/p/5292622.html

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

推荐阅读更多精彩内容