发现一篇比较好的极少RAC的文章,收录一下。git
最近在研究RAC,这两周准备整理一份RAC的学习笔记,敬请期待。github
原帖位置:https://www.jianshu.com/p/0845b1a07bfa。数组
2017.06.16 11:54* 字数 738 阅读 9812评论 11喜欢 63ide
ReactiveCocoa学习
RAC
指的就是RactiveCocoa
,是Github
的一个开源框架,可以帮咱们提供大量方便的事件处理方案,让咱们更简单粗暴地去处理事件,如今分为ReactiveObjC
和ReactiveSwift
,两个框架的功能使用类似,因为正好在学习这个而后公司项目是用OC
写的,因此将ReactiveObjC
的使用方法记录一下。atom
RAC
的核心思想:建立信号
- 订阅信号
- 发送信号
,而且在 RAC
中咱们会看到大量的 block
,因此在使用以前能够再从新温习一下 block
的使用。代理
/* 建立信号 */ RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) { /* 发送信号 */ [subscriber sendNext:@"发送信号"]; return nil; }]; /* 订阅信号 */ RACDisposable *disposable = [signal subscribeNext:^(id _Nullable x) { NSLog(@"信号内容:%@", x); }]; /* 取消订阅 */ [disposable dispose];
和代理的用法相似,一般用来代替代理,有了它,就没必要要定义代理了。code
/* 建立信号 */ RACSubject *subject = [RACSubject subject]; /* 发送信号 */ [subject sendNext:@"发送信号"]; /* 订阅信号(一般在别的视图控制器中订阅,与代理的用法相似) */ [subject subscribeNext:^(id _Nullable x) { NSLog(@"信号内容:%@", x); }];
RAC
的元祖,跟咱们 OC
的数组实际上是同样的,它其实就是封装了咱们 OC
的数组。server
/* 建立元祖 */ RACTuple *tuple = [RACTuple tupleWithObjects:@"1", @"2", @"3", @"4", @"5", nil]; /* 从别的数组中获取内容 */ RACTuple *tuple = [RACTuple tupleWithObjectsFromArray:@[@"1", @"2", @"3", @"4", @"5"]]; /* 利用 RAC 宏快速封装 */ RACTuple *tuple = RACTuplePack(@"1", @"2", @"3", @"4", @"5"); NSLog(@"取元祖内容:%@", tuple[0]); NSLog(@"第一个元素:%@", [tuple first]); NSLog(@"最后一个元素:%@", [tuple last]);
能够省去使用 for
循环来遍历。
/* 遍历数组 */ NSArray *array = @[@"1", @"2", @"3", @"4", @"5"]; [array.rac_sequence.signal subscribeNext:^(id _Nullable x) { NSLog(@"数组内容:%@", x); // x 能够是任何对象 }];
/* 遍历字典 */ NSDictionary *dictionary = @{@"key1":@"value1", @"key2":@"value2", @"key3":@"value3"}; [dictionary.rac_sequence.signal subscribeNext:^(RACTuple * _Nullable x) { RACTupleUnpack(NSString *key, NSString *value) = x; // x 是一个元祖,这个宏可以将 key 和 value 拆开 NSLog(@"字典内容:%@:%@", key, value); }];
下面两个方法都是将数组内容所有换为 0
,第一个是单个操做,,第二个是一次性所有替换,两个方法都不会改变原数组内容,操做完后都会生成一个新的数组,省去了建立可变数组而后遍历出来单个添加的步骤。
/* 内容操做 */ NSArray *array = @[@"1", @"2", @"3", @"4", @"5"]; NSArray *newArray = [[array.rac_sequence map:^id _Nullable(id _Nullable value) { NSLog(@"数组内容:%@", value); return @"0"; // 将全部内容替换为 0 }] array];
/* 内容快速替换 */ NSArray *array = @[@"1", @"2", @"3", @"4", @"5"]; NSArray *newArray = [[array.rac_sequence mapReplace:@"0"] array]; // 将全部内容替换为 0
能够省去设置 delegate
和实现代理方法的步骤。
/* 监听 TextField 的输入(内容改变就会调用) */ [[textField rac_textSignal] subscribeNext:^(NSString * _Nullable x) { NSLog(@"输入框内容:%@", x); }];
/* 添加监听条件 */ [[textField.rac_textSignal filter:^BOOL(NSString * _Nullable value) { return value.length > 5; // 表示输入文字长度 > 5 时才会调用下面的 block }] subscribeNext:^(NSString * _Nullable x) { NSLog(@"输入框内容:%@", x); }];
能够省去 addTarget
添加事件和建立方法的步骤。
[[button rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) { NSLog(@"%@ 按钮被点击了", x); // x 是 button 按钮对象 }];
下面表示只有 用户名
和 密码
输入框内容都大于 0
时,登陆
按钮才能够点击,并且状态是实时监听的,一句代码就能完成这个功能。
RAC(_loginButton, enabled) = [RACSignal combineLatest:@[_username.rac_textSignal, _password.rac_textSignal] reduce:^id _Nullable(NSString * username, NSString * password){ return @(username.length && password.length); }];
可省去在 -(void)dealloc {}
中清除通知和监听通知建立方法的步骤。
[[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardDidShowNotification object:nil] subscribeNext:^(NSNotification * _Nullable x) { NSLog(@"%@ 键盘弹起", x); // x 是通知对象 }];
能够省去监听以及设置 delegate
的步骤,下面表示只要 view
中执行了 btnClick
这个方法,就会发送信号执行这个回调。
[[view rac_signalForSelector:@selector(btnClick)] subscribeNext:^(RACTuple * _Nullable x) { NSLog(@" view 中的按钮被点击了"); }];
能够代替 KVO
监听,下面表示把监听 view
的 frame
属性改变转换成信号,只要值改变就会发送信号。
[[view rac_valuesForKeyPath:@"frame" observer:self] subscribeNext:^(id _Nullable x) { NSLog(@"属性的改变:%@", x); // x 是监听属性的改变结果 }];
还有一种更简单的写法,就是利用 RAC
的宏,和上面的效果是同样的。
[RACObserve(view, frame) subscribeNext:^(id _Nullable x) { NSLog(@"属性的改变:%@", x); // x 是监听属性的改变结果 }];
能够代替 NSTimer
使用。
@interface ViewController () @property (nonatomic, strong) RACDisposable *disposable; @end
/* 定义计时器监听 */ self.disposable = [[RACSignal interval:1.0 onScheduler:[RACScheduler mainThreadScheduler]] subscribeNext:^(NSDate * _Nullable x) { NSLog(@"当前时间:%@", x); // x 是当前的系统时间 /* 关闭计时器 */ [_disposable dispose]; }];
持续更新,学习到新的知识在记录下来,有须要的能够收藏一下。
未来的你,必定会感激如今拼命的本身,愿本身与读者的开发之路无限美好。