ReactiveCocoa简称RAC,是函数响应式编程框架,因为它具有函数式编程和响应式编程的特性。
- 由于该框架的编程思想,使得它具有相当魅惑人心的功能,它能实现传统设计模式和事件监听所能实现的功能,比如KVO、通知、block回调、action、协议等等,它的全面性并不是它最为优越的特色,RAC最值得炫耀的是它提供了统一的消息传递机制,这种机制使得它的代码更加的简洁,同一功能代码块更少,这正是符合了我们编程的思想:高聚合、低耦合,它非常适合MVVM设计模式的开发。
- 不过它也并不能完全取代传统的编码方式,在多人开发和代码维护方面,RAC还是有着一些让人头痛的问题。
优点: 使用灵活方便、代码简洁、逻辑清晰
缺点: 维护成本较高、问题溯源困难
使用: RAC的统一消息传递机制,其所以动作都离不开信号(sigal)。
- 1). 信号的创建、发送、接收
// 创建 此时为冷信号,并不会被触发
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscribersubscriber) {
// 发送信号
[subscriber sendNext:@"oh my god"];
// 回收资源。注意:手动创建一个signal一定要记得回收资源,不然程序会崩溃
return [RACDisposable disposableWithBlock:^{
NSLog(@"信号发送完成");
}];
}];
// 订阅信号后才会变为热信号,可以被触发
[signal subscribeNext:^(id x) {
NSLog(@"singalContent:%@", x);
}];
- 2). RAC的ControlEvents 这个方法可以简单的实现监听操作,并且逻辑在其后的
block中处理,而且也能添加手势并进行监听。
[[self.textField rac_signalForControlEvents:UIControlEventEditingDidBegin] subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
UITapGestureRecognizer *tap = [UITapGestureRecognizer new];
[[tap rac_gestureSignal] subscribeNext:^(id x) {
NSLog(@"three:%@", x);
}];
[self.view addGestureRecognizer:tap];
- 3). RAC的KVO
[[self.textField rac_valuesAndChangesForKeyPath:@"text" options:NSKeyValueObservingOptionNew observer:self] subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
- 4). RAC的通知
[[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardDidShowNotification object:nil] subscribeNext:^(id x) {
NSLog(@"键盘弹起");
}];
- 5). RAC的协议
- (void)viewDidLoad {
[super viewDidLoad];
// 代理
self.textField.delegate = self;
[[self rac_signalForSelector:@selector(textFieldDidBeginEditing:) fromProtocol:@protocol(UITextFieldDelegate)] subscribeNext:^(id x) {
NSLog(@"打印点击信息:%@", x);
}];
}
- (void)textFieldDidBeginEditing:(UITextField *)textField {
NSLog(@"开始编辑了");
}
- 6). RAC遍历数组和字典
相当于枚举遍历,但是效率相比更高
NSArray *arr = @[@"1", @"2", @"3", @"4", @"5"];
[arr.rac_sequence.signal subscribeNext:^(id x) {
NSLog(@"arr : %@", x);
}];
NSDictionary *dic = @{@"name":@"yangBo", @"age":@"19"};
[dic.rac_sequence.signal subscribeNext:^(id x) {
NSLog(@"dic : %@", x);
}];
- 7). RAC信号处理(map、filter、combine)
① 对信号不做处理
[[self.textField rac_textSignal] subscribeNext:^(id x) {
NSLog(@"doNothing:%@", x);
}];
② 对信号进行过滤(filter) 可以对信号进行条件判断是否处理。
[[[self.textField rac_textSignal] filter:^BOOL(NSString* value) {
if (value.length 3) {
return YES;
}
return NO;
}] subscribeNext:^(id x) {
NSLog(@"filter:%@", x);
}];
③ 对信号进行映射(map) 映射也可以理解为转换,第一个block返回的是id类型,如果返回"map now",就相当于信号转换,第二个block打印的值就是你return的值"map now"。
[[[self.textField rac_textSignal] map:^id(NSString* value) {
if (value.length 3) {
return @"map now";
}
return value;
}] subscribeNext:^(id x) {
NSLog(@"map:%@", x);
}];
④ 信号的联合(combine)
// 创建需要联合的信号
RACSignal *firstCombineSignal = [self.textField rac_textSignal];
RACSignal *secondeCombineSignal = [tap rac_gestureSignal];
// 信号联合处理返回self.label的背景色
RAC(self.label, backgroundColor) = [RACSignal combineLatest:@[firstCombineSignal, secondeCombineSignal] reduce:^id(NSString *text, UITapGestureRecognizer * tap){
// 这里进行信号逻辑判断和处理
if (text.length == 3 && tap.state == UIGestureRecognizerStateEnded) {
return [UIColor redColor];
}
return [UIColor cyanColor];
}];
⑤ 信号关联
RAC(self.label, text) = [self.textField rac_textSignal];