ReactiveCocoa入门(2)元祖、json解析、应用

来源:互联网 发布:手机淘宝怎么关注 编辑:程序博客网 时间:2024/06/06 04:17

3.3 元祖 RACTuple

什么叫做元祖?在 swift 中也有所谓的元祖,但是他跟 Objective-C 的数组有点不同。RAC的集合类

哪里不同呢?

  • swift 中的元祖,他可以放进任何的数据类型!也就是说基本数据类型也能放进去。
  • 但是 Objective-C 中的数组,它就只能放我们的 Objective-C 对象
  • 而 RAC 的元祖,跟我们的 Objective-C 数组其实是一样的,换句话说,它其实就是封装了我们的 Objective-C 数组。

    元祖
    Swift 中的元祖,他可以装进任何类型的数据
    OC 中的数组只能存放对象
    RAC 中的元祖,封装了一层 OC 的数组

我们来个简单的元祖:

RACTuple * tuple1 = [RACTuple tupleWithObjectsFromArray:@[@"apple",@"google",@123]]; NSString * str = tuple1[0];NSLog(@"%@",str);

它的用法跟我们的数组是一模一样的。
取出它的第一个元素:tuple1[0]
说白了其实他就是一个数组~

元祖其实只是 RAC 中的一个集合类,他还有其他的集合类。我们来看看其他的集合类是什么样的?

处理数组 - 遍历.png

数组遍历
只要一行,全部搞定!是不是相对于for循环来说简单多了,主要是编程思想:链式编程、函数编程、响应式编程!

我们来分析一下这段代码,
前面array.rac_sequence.signal 这种连续的点,是练式编程,后面的x 在风里雨里一直等着你,是响应式编程,最后我们再把所有的操作放在block 里面一顿操作,是函数式编程!

一句代码三个愿望一次满足!

处理字典

处理字典.png

二话不说先将它转成集合,转成集合之后我们创建一个信号,创建信号之后我们订阅这个信号,然后把信号内容全部拿出来

他打印了两组数据,也就是两个元祖,每个园组里面分别是key 还有value .所以说x 他是一个id 任意类型,所以我们应该可以把它改成我们的元祖类型然后我们既然把x 当作元祖类型,是不是就是说我们可以用元组类型的方法来调用它?

那就需要用到RAC中的宏RACTupleUnpack,RAC里牛逼之一就有它的宏,可以进去学习下!

Unpack 就是解包的意思,我们来看看怎么去用这个解包的,首先我们要给他赋值,把我们的元祖丢给这个宏。然后在他的参数里面写上参数类型还有参数名字。

在这边其实就是key 跟value
RACTupleUnpack(NSString * key, NSString * value) = x;

然后接下来我们把这个key 跟value 打印出来。

所以这边说明了~宏里面的参数其实就是需要被解析出来的变量名称!

解析 json 数据
首先创建个plist数据文件
flags.plist.png

第一步:建立模型#import <Foundation/Foundation.h>@interface FLAGES : NSObject@property(copy, nonatomic) NSString * name;@property(copy, nonatomic) NSString * icon;+(instancetype)flageWithDict:(NSDictionary *)dict;@end#import "FLAGES.h"@implementation FLAGES+(instancetype)flageWithDict:(NSDictionary *)dict{    FLAGES * flages = [[FLAGES alloc]init];    [flages setValuesForKeysWithDictionary:dict];    return flages;}@end第二步:回到我们的控制器 字典转模型//3、应用//    RACSequence 他可以代替我们的数组,也可以代替字典//    常用来解析 json 数据,最常使用的场合是 『字典转模型』    NSString * filePath = [[NSBundle mainBundle]pathForResource:@"flags.plist" ofType:nil];    NSArray * array2 = [NSArray arrayWithContentsOfFile:filePath];    //一般思维用法//    NSMutableArray * muArray = [NSMutableArray array];//    [array.rac_sequence.signal subscribeNext:^(NSDictionary * x) {//        //        //進行字典轉模型//        FLAGES * flages = [FLAGES flageWithDict:x];//        [muArray addObject:flages];//    }];    //升级版超爽用法    //value 集合里面所有的元素    NSArray * modelArray = [[array2.rac_sequence map:^id _Nullable(NSDictionary * value) {        return [FLAGES flageWithDict:value];    }]array];    NSLog(@"%@",modelArray);//    我们自己定义了一个可变数组,然后再给他每次接收信号的时候把它转成对象放到术组里面去。//    其实我们上下两边做的是一样的事情,此时此刻我们用了map 唯一的不同点是,他拿到了之后需要我们把这个对象给返回出去。因为它会自动帮我们把对象存到一个集合里面去。这个集合可以自动帮我们转成数组,因为它就是一个模型数组。

####常见应用
- 1、监听文本框
- 2、代替代理 RACSubject
- 3、代替 KVO
- 4、代替监听
- 5、代替通知

首先创建一个button,textFiled用作下面备用:

 //1、监听文本框 [_textF.rac_textSignal subscribeNext:^(NSString * _Nullable x) {     NSLog(@"%@",x); }];//2、代替代理 RACSubject (在第一篇中有说到RACSubject的使用,这个就是继承那个的使用方法)[[_redView rac_signalForSelector:@selector(btnClick:)] subscribeNext:^(RACTuple * _Nullable x) {    NSLog(@"%@",x);}];//3、代替 KVO//导入#import "NSObject+RACKVOWrapper.h"[[_btn rac_valuesForKeyPath:@"frame" observer:nil] subscribeNext:^(id  _Nullable x) {    NSLog(@"%@",x);}];//4、代替监听//把我们的点击事件当作信号[[_btn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {    NSLog(@"%@",x);}];//5、代替通知[[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardWillShowNotification object:nil] subscribeNext:^(NSNotification * _Nullable x) {    NSLog(@"%@",x);}];

利用RAC做一个按钮倒计时

 //#import "CountdownViewController.h"#import "ReactiveObjC.h"@interface CountdownViewController ()@property (nonatomic, assign) int time;@property (nonatomic, strong) RACDisposable *disposable;@end@implementation CountdownViewController-(IBAction)timeBtnClick:(UIButton *)sender {    sender.enabled = NO;    _time = 30;    //如果没有把 RACDisposable 强引用,RAC会给它自动转弱,执行一次完了    self.disposable = [[RACSignal interval:1.0 onScheduler:[RACScheduler mainThreadScheduler]] subscribeNext:^(NSDate * _Nullable x) {        //更新UI 设置按钮上的文字        //1、time > 0  , 按钮上的时间倒计时        //2、time <= 0 , 按钮上显示【重新发送】        //感觉太low了 下面改进//        if (_time > 0) {//            sender.enabled = NO;//            [sender setTitle:[NSString stringWithFormat:@"%ds",_time] forState:UIControlStateNormal];//        }else{//            sender.enabled = YES;//            [sender setTitle:@"重新发送" forState:UIControlStateNormal];//            //            //关闭 timer (取消订阅)//            [_disposable dispose];//        }        NSString *btnTitle = _time > 0 ? [NSString stringWithFormat:@"%ds",_time] : @"重新发送";        [sender setTitle:btnTitle forState:UIControlStateNormal];        if (_time > 0) {            sender.enabled = NO;        }else{            sender.enabled = YES;            //关闭 timer (手动取消订阅)            [_disposable dispose];        }        _time --;    }];    //滑动scrollView,timer不受影响}-(void)dealloc{    //只有当倒计时结束了,才会dealloc    NSLog(@"我走了");}

上述代码可以到我的GitHub中下载

有错误,有问题的欢迎提出来!��

未完待续…

原创粉丝点击