文丨清枫
什么是RAC
ReactiveCocoa(简称为RAC),是由Github开源的一个应用于iOS和OS开发的新框架,Cocoa是苹果整套框架的简称,因此很多苹果框架喜欢以Cocoa结尾。ReactiveCocoa5.0以后将 RAC 拆分为四个库:ReactiveCocoa、ReactiveSwift、ReactiveObjC、ReactiveObjCBridge。其中的ReactiveCocoa和ReactiveObjC,一个适用于纯Swift项目,另一个适用于纯OC项目。
RAC的作用
- 实现代理:rac_signalForSelector
- 代替KVO :rac_valuesAndChangesForKeyPath
- 监听事件:rac_signalForControlEvents
- 实现通知:rac_addObserverForName
- 监听文本框文字改变:rac_textSignal
- 处理当界面有多次请求时,需要都获取到数据时,才能展示界面
rac_liftSelector:withSignalsFromArray:Signals - 把要处理的事件和监听的事件放在一起,使代码高聚合,低耦合
函数式编程思想
函数式编程:就是尽可能的使用函数嵌套的方式来编程,函数式编程的目的就是尽可能的使代码高内聚,代表框架是ReactiveCocoa
函数式编程的方法签名要求:
- 方法的返回值是对象本身
- 方法的参数是Block
- Block的参数是需要操作的值
- Block的返回值是操作的结果
响应式编程思想:
响应式编程是一种面向数据流
和变化传播
的编程范式。编程语言中可以很方便地表达静态或动态的数据流,而相关的计算模型会自动将变化的值通过数据流进行传播。
在响应式编程中万物皆是流。 任何事物都可以当作一个流:变量、用户输入、属性、缓存、数据结构等等。
集成ReactiveCocoa
纯Swift项目Cocoapods导入
podfile文件中的内容:
platform:ios, ‘8.0’
use_frameworks!
target ‘这里写你的工程名’ do
pod 'ReactiveCocoa'
end
纯OC项目Cocoapods导入
podfile文件中的内容:
platform:ios, ‘8.0’
use_frameworks!
target ‘这里写你的工程名’ do
pod 'ReactiveObjC'
end
Tips:若项目为Swift和OC混编,那么需要将ReactiveObjC和ReactiveCocoa都导入,同时需要手动导入ReactiveObjCBridge。
RAC的使用(代码持续更新)
#import "ViewController.h"
#import "ReactiveObjC.h"
#import "NSObject+RACKVOWrapper.h"
@interface ViewController ()
@property(strong, nonatomic) id<RACSubscriber> subscriber;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//RACSignal:只能订阅信号,在内部由订阅者发送信号
//创建信号
RACSignal *signal = [RACSignal createSignal:^RACDisposable * (id<RACSubscriber> subscriber) {//订阅信号,执行subscribeNext时调用该代码块
//发送信号
[subscriber sendNext:@"MrFung"];
[subscriber sendCompleted];
return [RACDisposable disposableWithBlock:^{
NSLog(@"信号发送完成或者错误,执行此block取消订阅,当前信号不再被订阅");
}];
}];
//订阅信号
[signal subscribeNext:^(id x){//发送数据:调用sendNext时才会调用该代码块
NSLog(@"接收数据:%@", x);//接收数据:MrFung
}];
//RACDisposable:取消订阅
//创建信号
RACSignal *signal = [RACSignal createSignal:^RACDisposable * (id<RACSubscriber> subscriber) {
//发送信号
[subscriber sendNext:@"MrFung"];
_subscriber = subscriber;//全局变量保存起来,系统不会取消订阅
return [RACDisposable disposableWithBlock:^ {
NSLog(@"取消订阅,清理资源");
}];
}];
//订阅信号
RACDisposable *dispose = [signal subscribeNext:^(id x) {
NSLog(@"接受数据: %@", x);
}];
[dispose dispose];//主动取消订阅
//RACSubject:既能订阅信号,也能发送信号
//创建信号
RACSubject *subject = [RACSubject subject];
//订阅信号
[subject subscribeNext:^(id x) {
NSLog(@"接收到值: %@", x);
}];
//发送信号
[subject sendNext:@"MrFung"];
//RACReplaySubject:既可以先订阅信号再发送信号,也可以先发送信号再订阅信号
//先订阅再发送:
//创建信号
RACReplaySubject *replaySubject = [RACReplaySubject subject];
//订阅信号
[replaySubject subscribeNext:^(id x) {
NSLog(@"订阅者1接收到值: %@", x);
}];
//发送信号
[replaySubject sendNext:@"MrFung"];
//先发送再订阅:
//创建信号
RACReplaySubject *replaySubject = [RACReplaySubject subject];
//发送信号
[replaySubject sendNext:@"MrFung"];
//订阅信号
[replaySubject subscribeNext:^(id x) {
NSLog(@"订阅者1接收到值: %@", x);
}];
//RAC的KVO:
[self.view rac_observeKeyPath:@"alpha" options:NSKeyValueObservingOptionNew observer:nil block:^(id value, NSDictionary *change, BOOL causedByDealloc, BOOL affectedOnlyLastComponent) {
NSLog(@"change: %@", change);
}];
[[self.view rac_valuesAndChangesForKeyPath:@"backgroundColor" options:NSKeyValueObservingOptionNew observer:nil] subscribeNext:^(id x) {
NSLog(@"x:%@", x);
}];
//RAC按钮监听事件
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(100, 100, 200, 30)];
[button setTitle:@"Button" forState:UIControlStateNormal];
button.backgroundColor = [UIColor grayColor];
//监听和实现在一起
[[button rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^ (id x) {
NSLog(@"按钮被点击了:%@", x);
}];
[self.view addSubview:button];
//RAC通知:
[[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardWillShowNotification object:nil] subscribeNext:^(id x) {
NSLog(@"键盘即将显示");
}];
//RAC监听文本框内容
[[textField rac_textSignal] subscribeNext:^ (id x) {
NSLog(@"文本框内容改变了: %@", x);
}];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
self.view.backgroundColor = [UIColor grayColor];
self.view.alpha = 0.5;
}
@end
网友评论