ReactiveCocoa之基本使用

之前寫(xiě)了一篇關(guān)于ReactiveCocoa入門(mén)的文章,里面只是簡(jiǎn)單的介紹了ReactiveCocoa 的基本方法。接下來(lái)我會(huì)針對(duì)不同的方法 怎么使用做一下簡(jiǎn)單的介紹。

Tips:

cocoPods導(dǎo)入時(shí) oc : pod ‘ReactiveObjC’ swift : pod ‘ReactiveCocoa’ 詳細(xì)可查看官方介紹 http://reactivecocoa.io

話不多說(shuō)上代碼

RACSignal(信號(hào)類)

1、RAC 的核心就是RACSignal 它是一個(gè)信號(hào)類 一般需要三個(gè)步驟。

1.1 創(chuàng)建信號(hào)
1.2 訂閱信號(hào)
1.3 發(fā)送信號(hào)

 //創(chuàng)建信號(hào)
    RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        /**
         RACSubscriber 是一個(gè)協(xié)議類 只有遵循這個(gè)協(xié)議才能成為訂閱者
         */
        //發(fā)送信號(hào) 可以是任意類型
         [subscriber sendNext:self.dataArray];
        //信號(hào)發(fā)送成功
        [subscriber sendCompleted];
        
        return [RACDisposable disposableWithBlock:^{
        //銷毀信號(hào)
            
        }];
        
    }];
    
    //訂閱信號(hào)
    [signal subscribeNext:^(id  _Nullable x) {
        
        NSLog(@"接受數(shù)據(jù)---%@",x);
        
    }];

你可以這樣理解 你在某寶上相中了一款商品需要預(yù)付定金 等開(kāi)售的時(shí)候開(kāi)始給你發(fā)貨。預(yù)付定金相當(dāng)于訂閱信號(hào)、開(kāi)售發(fā)貨相當(dāng)于發(fā)送信號(hào)。是不是這個(gè)道理。

2、底層原理簡(jiǎn)單分析

2.1 創(chuàng)建信號(hào),首先把didSubscribe保存到信號(hào)中,還不會(huì)觸發(fā)。
2.2 當(dāng)信號(hào)被訂閱,也就是調(diào)用signal的subscribeNext:nextBlock
2.3 subscribeNext內(nèi)部會(huì)創(chuàng)建訂閱者subscriber,并且把nextBlock保存到subscriber中。
2.4 subscribeNext內(nèi)部會(huì)調(diào)用siganl的didSubscribe
2.5 signal的didSubscribe中調(diào)用[subscriber sendNext:id];
2.6 sendNext底層其實(shí)就是執(zhí)行subscriber的nextBlock
點(diǎn)擊這里可以查看RACSignal的常用用法

RACSubject

RACSubject:信號(hào)提供者,自己可以充當(dāng)信號(hào),又能發(fā)送信號(hào)。

 RACSubject *subject = [RACSubject subject];
  [subject subscribeNext:^(id  _Nullable x) {
        
   //訂閱信號(hào)
        
    }];
     //發(fā)送信號(hào)
    [subject sendNext:@"要發(fā)送的數(shù)據(jù)"];
- (RACDisposable *)subscribeNext:(void (^)(id x))nextBlock {
    NSCParameterAssert(nextBlock != NULL);
    
    RACSubscriber *o = [RACSubscriber subscriberWithNext:nextBlock error:NULL completed:NULL];
    return [self subscribe:o];
}

RACSubscriber:表示訂閱者的意思,用于發(fā)送信號(hào),這是一個(gè)協(xié)議,不是一個(gè)類,只要遵守這個(gè)協(xié)議,并且實(shí)現(xiàn)方法才能成為訂閱者。通過(guò)create創(chuàng)建的信號(hào),都有一個(gè)訂閱者,幫助他發(fā)送數(shù)據(jù)。

代替代理

利用RACSubject替換代理
SecondViewController.h 中 聲明一個(gè)RACSubject代理

@property (nonatomic,strong)RACSubject *delegateSignal;

SecondViewController.m 中 創(chuàng)建一個(gè)事件傳遞數(shù)據(jù)

 [[self.sendButton rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {

        if (self.delegateSignal) {
            //發(fā)送信號(hào)
            [self.delegateSignal sendNext:@"代理需要傳的數(shù)據(jù)"];
        }
        
    }];

跳轉(zhuǎn)SecondViewController時(shí)接受代理

 [[self.signalButton rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
        
        NSLog(@"button點(diǎn)擊事件 ---%@",x);
        SecondViewController *second = [[SecondViewController alloc] init];
        second.title = @"second";
        //設(shè)置代理信號(hào)----創(chuàng)建信號(hào)
        second.delegateSignal = [RACSubject subject];
        //訂閱代理信號(hào)----訂閱信號(hào)
        [second.delegateSignal subscribeNext:^(id x) {
            
            NSLog(@"%@",x);
            
        }];
        [self.navigationController pushViewController:second animated:YES];
        
    }];

代替通知

//注冊(cè)通知
 [[[NSNotificationCenter defaultCenter] rac_addObserverForName:@"notification" object:nil] subscribeNext:^(NSNotification * notification) {
        
        NSLog(@"收到通知 notification.name=%@ notification.object=%@",notification.name,notification.object);
        
    }];
//發(fā)送通知
[[NSNotificationCenter defaultCenter] postNotificationName:@"notification" object:@"通知傳值"];

代替KVO

這里 以監(jiān)聽(tīng)UITextField的text變動(dòng)為例。

#pragma mark KVO監(jiān)聽(tīng)
    
    [[self.textField rac_valuesAndChangesForKeyPath:@"text" options:NSKeyValueObservingOptionNew observer:@""] subscribeNext:^(RACTwoTuple<id,NSDictionary *> * _Nullable x) {
        
        NSLog(@"KVO監(jiān)聽(tīng)結(jié)果:%@",x);
        
    }];

監(jiān)聽(tīng)某個(gè)對(duì)象的某個(gè)屬性,返回的是信號(hào) 可用于搜索返回結(jié)果展示。聯(lián)想一下音樂(lè)播放器搜歌。

#pragma mark 監(jiān)聽(tīng)某個(gè)對(duì)象的某個(gè)屬性,返回的是信號(hào)
    [RACObserve(self,changeString)
     subscribeNext:^(NSString* x){
         
         NSLog(@"RACObserve ----%@--",x);
         
     }];
//監(jiān)聽(tīng)判斷 
 [[RACObserve(self, changeString)filter:^BOOL(id  _Nullable value) {
        
        return [value  isEqualToString:@"開(kāi)始"] ? YES : NO;
        
    }] subscribeNext:^(id  _Nullable x) {
        
        //滿足上面條件才能執(zhí)行
        NSLog(@"x---終于輪到我展示了");
        
    }] ;

監(jiān)聽(tīng)事件

這里只展示開(kāi)發(fā)者中常用的點(diǎn)擊事件。以UIButton的點(diǎn)擊事件和UILabel的手勢(shì)為例。

#pragma mark button 點(diǎn)擊事件
[[self.signalButton rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
      
      NSLog(@"button點(diǎn)擊事件 ---%@",x);

      [self.navigationController pushViewController:second animated:YES];
      
  }];
//button事件監(jiān)聽(tīng)的另一種方法
self.signalButton.rac_command = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id  _Nullable input) {
      
      NSLog(@"接受button事件的第二張方法");
      
      return [RACSignal empty];
  }];

#pragma mark UILabel 手勢(shì)
  
  UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] init];
  
  [[tap rac_gestureSignal] subscribeNext:^(id x) {
      
      NSLog(@"label手勢(shì)---%@",x);
    
  }];
[self.myLabel addGestureRecognizer:tap];

文本監(jiān)測(cè)

主要針對(duì)于 UITextField、UITextView文本的監(jiān)測(cè)可代替自身的代理。

 #pragma mark UITextField 文本監(jiān)測(cè)
     @weakify(self)
     [self.textField.rac_textSignal subscribeNext:^(NSString *x) {
      @strongify(self)
        NSLog(@"%@",x);
        
        self.changeString = x;
        
    }];

替代遍歷

1、數(shù)組遍歷
 NSArray *numbers = @[@1,@2,@3,@4,@5];
    
    [numbers.rac_sequence.signal subscribeNext:^(id  _Nullable x) {
        
        NSLog(@"NSArray ---- %@",x);

    }];
2、字典遍歷
 NSDictionary *dict = @{@"name":@"wang",@"age":@"18"};
    
    [dict.rac_sequence.signal subscribeNext:^(RACTuple *x) {
        
        RACTupleUnpack(NSString *key,NSString*value) = x;
        
        NSLog(@"NSDictionary ----- key=%@ value=%@",key,value);
        
    }];
3、字典轉(zhuǎn)模型
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"ClassList.plist" ofType:nil];
    NSArray *dictArr = [NSArray arrayWithContentsOfFile:filePath];
    NSMutableArray *modelArray = [NSMutableArray array];
    
    [dictArr.rac_sequence.signal subscribeNext:^(id  _Nullable x) {
        
        NSLog(@"字典轉(zhuǎn)模型 %@",x);
        
        classModel *model = [classModel modelObjectWithDictionary:x];
        
        [modelArray addObject:model];
        
        //        NSLog(@"名字----%@",model.name);
        
    }] ;
//簡(jiǎn)單粗暴的寫(xiě)法
 NSArray *flags = [[dictArr.rac_sequence map:^id(id value) {
        
        return [classModel  modelObjectWithDictionary:value];
        
    }] array];

進(jìn)入相冊(cè)選擇照片

self.pictureButton.rac_command = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id  _Nullable input) {
        
        UIImagePickerController *pickerController = [UIImagePickerController new];
        pickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
        [pickerController.rac_imageSelectedSignal subscribeNext:^(NSDictionary * info) {
            
            UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
            
            self.myImageView.image = image;
            [pickerController dismissViewControllerAnimated:YES completion:nil];
            
        }];
        //取消
        [[pickerController.rac_delegateProxy signalForSelector:@selector(imagePickerControllerDidCancel:)] subscribeNext:^(id  _Nullable x) {
            
            [pickerController dismissViewControllerAnimated:YES completion:nil];
        }];
        //跳轉(zhuǎn)
        [self presentViewController:pickerController animated:YES completion:nil];
        
        
        return [RACSignal empty];
    }];

至今已經(jīng)熟悉運(yùn)用的這么多。是不是比你用的要簡(jiǎn)單。先掌握熟悉運(yùn)用。至于原理學(xué)習(xí)了解了再告訴大家。

參考文檔

http://www.itdecent.cn/p/e10e5ca413b7
http://www.itdecent.cn/p/a4fefb434652
https://blog.csdn.net/jia12216/article/details/55520151
https://blog.csdn.net/wzc10101415/article/details/55051339
https://blog.csdn.net/y_csdnblog_xx/article/details/51480181
https://www.cnblogs.com/develop-SZT/p/5292622.html

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

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