美文网首页
ReactiveCocoa入门(2)元祖、json解析、应用

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

作者: 子疯zp | 来源:发表于2017-05-14 17:41 被阅读80次
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](https://img.haomeiwen.com/i1859446/6792e7843aa049b3.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

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

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

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

**处理字典**

![处理字典.png](https://img.haomeiwen.com/i1859446/b9ecf6a4469ba812.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

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

![](https://img.haomeiwen.com/i1859446/bc417c232083cd99.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)


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

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


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

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

然后接下来我们把这个key 跟value 打印出来。
![](https://img.haomeiwen.com/i1859446/0a5df30546bb09d2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
所以这边说明了~宏里面的参数其实就是需要被解析出来的变量名称!


**解析 json 数据**
首先创建个plist数据文件
![flags.plist.png](https://img.haomeiwen.com/i1859446/6951bb463631a54d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

第一步:建立模型

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](https://github.com/zpHao/ReactiveCocoa-primary)中下载

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



*未完待续...*

相关文章

网友评论

      本文标题:ReactiveCocoa入门(2)元祖、json解析、应用

      本文链接:https://www.haomeiwen.com/subject/xrmqxxtx.html