簡介
RAC(ReactiveCocoa)是一款響應式編程的框架迹缀,處理事件邏輯空另,代理通知KVO都可以使用RAC來解決漾岳。利用好它可以省1/2的邏輯代碼狸臣。夠吸引你嗎莹桅?那就開始學習吧,向大神邁進烛亦。
1.CocoaPods導入
OC: pod 'ReactiveCocoa', '~> 2.5'
Swift:pod 'ReactiveCocoa'
2.信號RACSignal
- RACSiganl:信號類,一般表示將來有數(shù)據(jù)傳遞诈泼,只要有數(shù)據(jù)改變,信號內部接收到數(shù)據(jù)煤禽,就會馬上發(fā)出數(shù)據(jù)铐达。就像發(fā)送通知一樣。
- RACSubscriber:表示訂閱者的意思檬果,用于發(fā)送信號瓮孙,這是一個協(xié)議唐断,不是一個類,只要遵守這個協(xié)議杭抠,并且實現(xiàn)方法才能成為訂閱者脸甘。就像注冊通知一樣。
- RACDisposable:用于取消訂閱或者清理資源偏灿,當信號發(fā)送完成或者發(fā)送錯誤的時候丹诀,就會自動觸發(fā)它。就像銷毀通知一樣翁垂。
- 其他類高級使用中講到铆遭。
3.RAC常見用法
-
代替代理
rac_signalForSelector
自定義view上有個按鈕。
[[self.redView rac_signalForSelector:@selector(btnClick:)] subscribeNext:^(id x) {
NSLog(@"點擊了紅色按鈕");
}];
-
代替KVO
rac_valuesAndChangesForKeyPath
監(jiān)聽view的屬性變化
[[self.redView rac_valuesAndChangesForKeyPath:@"center" options:NSKeyValueObservingOptionNew observer:nil] subscribeNext:^(id x) {
NSLog(@"位置變了");
}];
-
監(jiān)聽事件
rac_signalForControlEvents
監(jiān)聽各類事件
[[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
監(jiān)聽textfield的變化
[self.password.rac_textSignal subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
-
多事件完成后統(tǒng)一處理
rac_liftSelector:withSignalsFromArray:Signals
多網(wǎng)絡請求后統(tǒng)一更新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);
}
-
信號隊列,處理多事件順序執(zhí)行
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