ReactiveCocoa 更優(yōu)雅的編程(基礎(chǔ)使用)

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

  • 相關(guān)文章
    ReactiveCocoa 更優(yōu)雅的編程(信號探秘)

  • ReactiveCocoa 分為四個庫:ReactiveCocoa、ReactiveSwift、ReactiveObjC、ReactiveObjCBridge。
    ReactiveObjC 是 RAC的Object-C版本
    使用CocoaPods導(dǎo)入
    在導(dǎo)入過程中 podfile如果只描述pod 'ReactiveObjC' 會提示有問題,需要在podfile加上use_frameworks?。ǜ袊@號也不能少),重新pod install 才能導(dǎo)入成功。

    F6D49946-866A-4E3E-BECA-9242ABEB245B.png

這篇 先寫一些常用的 基礎(chǔ)方法 方便以后復(fù)制粘貼??,以后計劃再寫一個小項目 基于RAC+MVVM 到時候在結(jié)合項目寫一篇

  • 數(shù)組
//數(shù)組遍歷 
    NSArray *array = @[@"1", @"2", @"3", @"4", @"5"];
    [array.rac_sequence.signal subscribeNext:^(id  _Nullable x) {
        NSLog(@"遍歷數(shù)組 %@",x);
    }];
// 數(shù)組內(nèi)容替換 并生成一個新的數(shù)組
NSArray *newArray = [[array.rac_sequence mapReplace:@"one"] array]; 
NSLog(@"newArray %@",newArray);
  • 元祖
    元祖和OC 的數(shù)組差不多
//創(chuàng)建元祖 
RACTuple *tuple = [RACTuple tupleWithObjects:@"1", @"2", @"3", @"4", @"5", nil];

// 從數(shù)組中獲取內(nèi)容 
RACTuple *tuple = [RACTuple tupleWithObjectsFromArray: array];

//  宏創(chuàng)建 
RACTuple *tuple = RACTuplePack(@"1", @"2", @"3", @"4", @"5");
NSLog(@"按下標(biāo)取內(nèi)容:%@", 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(@"字典內(nèi)容:%@:%@", 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 計時器 ,以往我們使用系統(tǒng)的計時器,不管是 NSTimer 方法還是 GCD 的方法 要不是 要記得及時釋放,要不就寫一大推。RAC 如此簡單就搞定 感覺不要太爽。
  //多長時間后執(zhí)行一次
 [[RACScheduler mainThreadScheduler]afterDelay:3 schedule:^{
        NSLog(@"3秒后執(zhí)行一次");
  }];

 //takeUnti作用是  當(dāng)控制器消失后取消執(zhí)行
 RACDisposable *dispo=[[[RACSignal interval:2 onScheduler:[RACScheduler mainThreadScheduler]] takeUntil:self.rac_willDeallocSignal ] subscribeNext:^(id x) {
        NSLog(@"每兩秒執(zhí)行一次");     
 }];
[dispo dispose]; //停止定時器
  • 代替代理 以往我們控制器上有View 上面有按鈕有點擊事件,這個需求很常見,如果是用代理完成看看我們需要寫什么,
    1.View.h 中寫 協(xié)議, 定義屬性
    2.View.m 中在方法里調(diào)用代理
    3.在控制器中遵守協(xié)議 設(shè)置代理
    4.寫代理方法
    感覺一大推 很麻煩RAC 就在控制器中 用按鈕所在的View調(diào)用一個方法就搞定。 這屬于RAC的發(fā)送信號機制的基本表現(xiàn),注意:調(diào)用的方法名字一定要寫對
//代替代理
[[self.subView rac_signalForSelector:@selector(btnClick)] subscribeNext:^(RACTuple * _Nullable x) {
        NSLog(@" view 中的按鈕被點擊了");
 }];
  • 代替代理2
    1.給當(dāng)前控制器添加一個按鈕,modal到另一個控制器界面
    2.另一個控制器view中有個按鈕,點擊按鈕,通知當(dāng)前控制器
步驟一:在第二個控制器.h,添加一個RACSubject代替代理。
@interface TwoViewController : UIViewController

@property (nonatomic, strong) RACSubject *delegateSignal;

@end

步驟二:監(jiān)聽第二個控制器按鈕點擊
@implementation TwoViewController
- (IBAction)notice:(id)sender {
    // 通知第一個控制器,告訴它,按鈕被點了
    
     // 通知代理
     // 判斷代理信號是否有值
    if (self.delegateSignal) {
        // 有值,才需要通知
        [self.delegateSignal sendNext:nil];
    }
}
@end

步驟三:在第一個控制器中,監(jiān)聽跳轉(zhuǎn)按鈕,給第二個控制器的代理信號賦值,并且監(jiān)聽.
@implementation OneViewController 
- (IBAction)btnClick:(id)sender {
    // 創(chuàng)建第二個控制器
    TwoViewController *twoVc = [[TwoViewController alloc] init];
    // 設(shè)置代理信號
    twoVc.delegateSignal = [RACSubject subject];
    // 訂閱代理信號
    [twoVc.delegateSignal subscribeNext:^(id x) {
        NSLog(@"點擊了通知按鈕");
    }];
    // 跳轉(zhuǎn)到第二個控制器
    [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);
  }];
  • 監(jiān)聽 TextField 的輸入改變 告別代理了
 監(jiān)聽 TextField 的輸入
[[textField rac_textSignal] subscribeNext:^(NSString * _Nullable x) {
    NSLog(@"內(nèi)容:%@", x);
}];
//也可以添加判斷條件
[[textField.rac_textSignal filter:^BOOL(NSString * _Nullable value) {
    return value.length > 10; // 文字長度 > 10 在監(jiān)聽
}] subscribeNext:^(NSString * _Nullable x) {

     NSLog(@"輸入框內(nèi)容:%@", x);
}];

  • 監(jiān)聽 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];

結(jié)尾:水平有限,代碼也很爛,一直在努力學(xué)習(xí)中,大家多多包涵。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容