简介
RAC(ReactiveCocoa)是一款响应式编程的框架,处理事件逻辑,代理通知KVO都可以使用RAC来解决。利用好它可以省1/2的逻辑代码。够吸引你吗?那就开始学习吧,向大神迈进。
1.CocoaPods导入
OC: pod 'ReactiveCocoa', '~> 2.5'
Swift:pod 'ReactiveCocoa'
2.信号RACSignal
- RACSiganl:信号类,一般表示将来有数据传递,只要有数据改变,信号内部接收到数据,就会马上发出数据。就像发送通知一样。
- RACSubscriber:表示订阅者的意思,用于发送信号,这是一个协议,不是一个类,只要遵守这个协议,并且实现方法才能成为订阅者。就像注册通知一样。
- RACDisposable:用于取消订阅或者清理资源,当信号发送完成或者发送错误的时候,就会自动触发它。就像销毁通知一样。
- 其他类高级使用中讲到。
3.RAC常见用法
-
代替代理
rac_signalForSelector
自定义view上有个按钮。
[[self.redView rac_signalForSelector:@selector(btnClick:)] subscribeNext:^(id x) {
NSLog(@"点击了红色按钮");
}];
-
代替KVO
rac_valuesAndChangesForKeyPath
监听view的属性变化
[[self.redView rac_valuesAndChangesForKeyPath:@"center" options:NSKeyValueObservingOptionNew observer:nil] subscribeNext:^(id x) {
NSLog(@"位置变了");
}];
-
监听事件
rac_signalForControlEvents
监听各类事件
[[self.testButton rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(id x) {
NSLog(@"点击了button%@",x);
}];
-
代替通知
rac_addObserverForName
代替通知
[[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardWillShowNotification object:nil] subscribeNext:^(NSNotification *notification) {
NSDictionary *info = notification.userInfo;
NSValue *keyboardFrameValue = [info objectForKey:UIKeyboardFrameEndUserInfoKey];
CGRect keyboardFrame = keyboardFrameValue.CGRectValue;
NSLog(@"height----%f",keyboardFrame.size.height);
}];
-
文字框变化
rac_textSignal
监听textfield的变化
[self.password.rac_textSignal subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
-
多事件完成后统一处理
rac_liftSelector:withSignalsFromArray:Signals
多网络请求后统一更新UI
RACSignal *request1 = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[subscriber sendNext:@"请求1"];
NSLog(@"11111");
});
return nil;
}];
RACSignal *request2 = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(8.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[subscriber sendNext:@"请求2"];
NSLog(@"222");
});
return nil;
}];
[self rac_liftSelector:@selector(updateUIWithR1:r2:) withSignalsFromArray:@[request1,request2]];
//更新UI
- (void)updateUIWithR1:(id)data1 r2:(id)data2
{
NSLog(@"更新UI%@----%@",data1,data2);
}
-
信号队列,处理多事件顺序执行
RACSignal *singal1 = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@"one"];
return nil;
}];
RACSignal *singal2 = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@"two"];
return nil;
}];
RACSignal *singal3 = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@"three"];
return nil;
}];
[[RACSignal merge:@[singal3,singal2,singal1]] subscribeNext:^(id x) {
NSLog(@"信号队列----%@",x);
}];
-
宏
RAC(self.passwordLabel, text) = self.password.rac_textSignal;
RACTuple *tuple = RACTuplePack(@"hl",@24);
RACTupleUnpack(NSString *name,NSNumber *age) = tuple;
NSLog(@"%@---%@",name,age);
[RACObserve(self.redView, center) subscribeNext:^(id x) {
NSLog(@"333%@",x);
}];
-
组合操作
[self.phoneTextField.rac_textSignal subscribeNext:^(NSString *x) {
self.phone = x;
}];
[self.passwordTextField.rac_textSignal subscribeNext:^(NSString *x) {
self.pswd = x;
}];
[[[RACSignal combineLatest:@[RACObserve(self, phone),RACObserve(self, pswd)] reduce:^(NSString *txt1,NSString *txt2){
return @(txt1.length > 2 && txt2.length > 2);
}] distinctUntilChanged] subscribeNext:^(NSNumber *x) {
if ([x boolValue]) {
NSLog(@"yes");
}else {
NSLog(@"no");
}
}];
最后
demo地址:github
网友评论