ReactiveCocoa(簡稱為RAC),是由Github開源的一個應用于iOS和OS開發的框架.
ReactiveCocoa 優點大家或多或少都有所了解,不管是 處理業務邏輯 還是 降低耦合度方面都是非常好,我感覺最棒的還是RAC的編程思想,函數響應式編程 ,不需要考慮調用順序,和太多邏輯,直接考慮結果,把每一次操作都寫成一系列嵌套的方法中,使代碼高聚合,方便管理。我最近的的寫代碼方式 也在慢慢被RAC改變。
-
ReactiveCocoa 分為四個庫:ReactiveCocoa、ReactiveSwift、ReactiveObjC、ReactiveObjCBridge。
ReactiveObjC 是 RAC的Object-C版本
使用CocoaPods導入
在導入過程中 podfile如果只描述pod 'ReactiveObjC' 會提示有問題,需要在podfile加上use_frameworks!(感嘆號也不能少),重新pod install 才能導入成功。
F6D49946-866A-4E3E-BECA-9242ABEB245B.png
這篇 先寫一些常用的 基礎方法 方便以后復制粘貼??,以后計劃再寫一個小項目 基于RAC+MVVM 到時候在結合項目寫一篇
- 數組
//數組遍歷
NSArray *array = @[@"1", @"2", @"3", @"4", @"5"];
[array.rac_sequence.signal subscribeNext:^(id _Nullable x) {
NSLog(@"遍歷數組 %@",x);
}];
// 數組內容替換 并生成一個新的數組
NSArray *newArray = [[array.rac_sequence mapReplace:@"one"] array];
NSLog(@"newArray %@",newArray);
- 元祖
元祖和OC 的數組差不多
//創建元祖
RACTuple *tuple = [RACTuple tupleWithObjects:@"1", @"2", @"3", @"4", @"5", nil];
// 從數組中獲取內容
RACTuple *tuple = [RACTuple tupleWithObjectsFromArray: array];
// 宏創建
RACTuple *tuple = RACTuplePack(@"1", @"2", @"3", @"4", @"5");
NSLog(@"按下標取內容:%@", tuple[2]);
NSLog(@"第一個元素:%@", [tuple first]);
NSLog(@"最后一個元素:%@", [tuple last]);
- 字典
字典遍歷
NSDictionary *dict = @{@"name":@"韓梅梅", @"age":@"19",@"lovers":@"╮(╯_╰)╭"};
[dict.rac_sequence.signal subscribeNext:^(RACTuple * _Nullable x) {
NSLog(@"遍歷字典 %@",x);
//RACTupleUnpack 是個宏 可快速分開Key value
RACTupleUnpack(NSString *key, NSString *value) = x
NEWSLog(@"字典內容:%@:%@", key, value);
}];
- Button點擊事件 代碼放在一起,這樣非常方便我們管理
UIButton *btn=[UIButton buttonWithType:UIButtonTypeRoundedRect];
btn.frame=CGRectMake(100, 100, 100, 100);
[btn setTitle:@"點擊" forState:UIControlStateNormal];
[self.view addSubview:btn];
[[btn rac_signalForControlEvents:UIControlEventTouchUpInside]subscribeNext:^(__kindof UIControl * _Nullable x) {
NSLog(@"??哈哈哈");
}];
- NSTimer 計時器 ,以往我們使用系統的計時器,不管是 NSTimer 方法還是 GCD 的方法 要不是 要記得及時釋放,要不就寫一大推。RAC 如此簡單就搞定 感覺不要太爽。
//多長時間后執行一次
[[RACScheduler mainThreadScheduler]afterDelay:3 schedule:^{
NSLog(@"3秒后執行一次");
}];
//takeUnti作用是 當控制器消失后取消執行
RACDisposable *dispo=[[[RACSignal interval:2 onScheduler:[RACScheduler mainThreadScheduler]] takeUntil:self.rac_willDeallocSignal ] subscribeNext:^(id x) {
NSLog(@"每兩秒執行一次");
}];
[dispo dispose]; //停止定時器
- 代替代理 以往我們控制器上有View 上面有按鈕有點擊事件,這個需求很常見,如果是用代理完成看看我們需要寫什么,
1.View.h 中寫 協議, 定義屬性
2.View.m 中在方法里調用代理
3.在控制器中遵守協議 設置代理
4.寫代理方法
感覺一大推 很麻煩RAC 就在控制器中 用按鈕所在的View調用一個方法就搞定。 這屬于RAC的發送信號機制的基本表現,注意:調用的方法名字一定要寫對
//代替代理
[[self.subView rac_signalForSelector:@selector(btnClick)] subscribeNext:^(RACTuple * _Nullable x) {
NSLog(@" view 中的按鈕被點擊了");
}];
- 代替代理2
1.給當前控制器添加一個按鈕,modal到另一個控制器界面
2.另一個控制器view中有個按鈕,點擊按鈕,通知當前控制器
步驟一:在第二個控制器.h,添加一個RACSubject代替代理。
@interface TwoViewController : UIViewController
@property (nonatomic, strong) RACSubject *delegateSignal;
@end
步驟二:監聽第二個控制器按鈕點擊
@implementation TwoViewController
- (IBAction)notice:(id)sender {
// 通知第一個控制器,告訴它,按鈕被點了
// 通知代理
// 判斷代理信號是否有值
if (self.delegateSignal) {
// 有值,才需要通知
[self.delegateSignal sendNext:nil];
}
}
@end
步驟三:在第一個控制器中,監聽跳轉按鈕,給第二個控制器的代理信號賦值,并且監聽.
@implementation OneViewController
- (IBAction)btnClick:(id)sender {
// 創建第二個控制器
TwoViewController *twoVc = [[TwoViewController alloc] init];
// 設置代理信號
twoVc.delegateSignal = [RACSubject subject];
// 訂閱代理信號
[twoVc.delegateSignal subscribeNext:^(id x) {
NSLog(@"點擊了通知按鈕");
}];
// 跳轉到第二個控制器
[self presentViewController:twoVc animated:YES completion:nil];
}
@end
- 代替KVO
[[self rac_valuesForKeyPath:@"name" observer:self] subscribeNext:^(id _Nullable x) {
NSLog(@"name屬性的改變:%@", x);
}];
//RACObserve 宏寫法
[RACObserve(self, self.name) subscribeNext:^(id _Nullable x) {
NSLog(@"name屬性的改變111:%@", x);
}];
- 監聽 TextField 的輸入改變 告別代理了
監聽 TextField 的輸入
[[textField rac_textSignal] subscribeNext:^(NSString * _Nullable x) {
NSLog(@"內容:%@", x);
}];
//也可以添加判斷條件
[[textField.rac_textSignal filter:^BOOL(NSString * _Nullable value) {
return value.length > 10; // 文字長度 > 10 在監聽
}] subscribeNext:^(NSString * _Nullable x) {
NSLog(@"輸入框內容:%@", x);
}];
- 監聽 Notification 通知事件 以往 還要清除通知 有了RAC 不在那么麻煩
[[[NSNotificationCenter defaultCenter] rac_addObserverForName:NIGHT object:nil] subscribeNext:^(id x) {
NSLog(@"夜間模式:%@",x);
}];
- 手勢 代碼放在一起,這樣非常方便我們管理
UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] init];
[panGesture.rac_gestureSignal subscribeNext:^(id x) {
NSLog(@"拖動手勢:%@", x);
}];
[self.view addGestureRecognizer:panGesture];
結尾:水平有限,代碼也很爛,一直在努力學習中,大家多多包涵。