ReactiveCocoa 更優雅的編程(基礎使用)

ReactiveCocoa(簡稱為RAC),是由Github開源的一個應用于iOS和OS開發的框架.
ReactiveCocoa 優點大家或多或少都有所了解,不管是 處理業務邏輯 還是 降低耦合度方面都是非常好,我感覺最棒的還是RAC的編程思想,函數響應式編程 ,不需要考慮調用順序,和太多邏輯,直接考慮結果,把每一次操作都寫成一系列嵌套的方法中,使代碼高聚合,方便管理。我最近的的寫代碼方式 也在慢慢被RAC改變。

  • 相關文章
    ReactiveCocoa 更優雅的編程(信號探秘)

  • 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];

結尾:水平有限,代碼也很爛,一直在努力學習中,大家多多包涵。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容