iOS RAC常用方法總結

簡介:本文主要對RAC常見使用方法及易混淆的概念和注意事項進行匯總,方便后續(xù)查詢和學習。原文請參考:《ReactiveCocoa 概述》《zwcshy/RAC》常見問題請參考《iOS RAC常見問題匯總》

1.代替代理

//代理
[[self rac_signalForSelector:@selector(tableView:didSelectRowAtIndexPath:) fromProtocol:@protocol(UITableViewDelegate)] subscribeNext:^(id x) {
            
}];

2.監(jiān)聽事件

按鈕點擊

[[self.button rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(id x) {
        
}];

文本內容變化

[[self.textField rac_textSignal] subscribeNext:^(NSString * _Nullable x) {
     
}];

手勢事件

UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]init];
[tap.rac_gestureSignal subscribeNext:^(id x) {

}];

3.通知

[[[NSNotificationCenter defaultCenter] rac_addObserverForName:@"name" object:nil] subscribeNext:^(id x) {
        
}];

4.KVO

//方法1
[[self rac_valuesAndChangesForKeyPath:@"title" options:NSKeyValueObservingOptionNew observer:nil] subscribeNext:^(id x) {
        
}];
//方法2
[[self rac_valuesForKeyPath:@"title" observer:nil] subscribeNext:^(id x) {
        
}];
//方法3
[RACObserve(self, title) subscribeNext:^(id x) {
        
}];

5.定時器

//定時器
RACDisposable * disposable = [[RACSignal interval:1 onScheduler:[RACScheduler scheduler]] subscribeNext:^(id x) {
        
}];
    
//釋放定時器
[disposable dispose];

6.集合遍歷RACSequence

數(shù)組遍歷

//默認在子線程中遍歷
NSArray *numbers = @[@"1",@"2",@"3",@"4"];
[numbers.rac_sequence.signal subscribeNext:^(id x) {
  NSLog(@"%@",x);
}];
//放在主線程中遍歷
[[numbers.rac_sequence.signal deliverOn:[RACScheduler mainThreadScheduler]] subscribeNext:^(id  _Nullable x) {
        
}];

字典遍歷

NSDictionary * dic = @{
    @"1":@"1111",
    @"2":@"2222",
    @"3":@"3333",
    @"4":@"4444"
};

[dic.rac_sequence.signal subscribeNext:^(id x) {
    RACTupleUnpack(NSString * key,NSObject * value) = x;
    NSLog(@"key=%@,value=%@",key,value);
}];

字符串遍歷

NSString *text = @"123456789";
[text.rac_sequence.signal subscribeNext:^(id x) {
   NSLog(@"%@",x);
}];

7.映射Map(生成新的值)flattenMap(生成新的信號)

map(生成新的值)

NSArray * newNumbers = [numbers.rac_sequence map:^id(id value) {
    return  [NSString stringWithFormat:@"numbers: %@",value];
}].array;

flattenMap(生成新的信號)

// 創(chuàng)建信號
RACSubject *subject = [RACSubject subject];
// 綁定信號
RACSignal *bindSignal = [subject flattenMap:^RACStream *(id value) {
// value: 就是源信號發(fā)送的內容
// 返回信號用來包裝成修改內容的值
return [RACReturnSignal return:value];

}];
// flattenMap中返回的是什么信號,訂閱的就是什么信號(那么,x的值等于value的值,如果我們操縱value的值那么x也會隨之而變)
// 訂閱信號
[bindSignal subscribeNext:^(id x) {
NSLog(@"%@", x);
}];

// 發(fā)送數(shù)據(jù)
[subject sendNext:@"123"];

8.延時執(zhí)行

throttle:延時調用block(subscribeNext)

[[[self.button rac_signalForControlEvents:UIControlEventTouchUpInside] throttle:5] subscribeNext:^(id x) {
        
}];

delay:延遲調用

[[[self.button rac_signalForControlEvents:UIControlEventTouchUpInside] delay:5] subscribeNext:^(id x) {
         
}];

timeout:超時后則不調用block

[[self.signal timeout:5 onScheduler:[RACScheduler scheduler]] subscribeNext:^(id x) {
}];

延時執(zhí)行

[[RACScheduler scheduler] after:[NSDate dateWithTimeIntervalSinceNow:3] schedule:^{
           
 }];

9.過濾

filter接受滿足條件的信號

[[numbers.rac_sequence.signal filter:^BOOL(id value) {
    return [value integerValue] > 3;
}] subscribeNext:^(id x) {
        
}];
// 只有當文本框的內容長度大于5,才獲取文本框里的內容
[[self.textField.rac_textSignal filter:^BOOL(id value) {
// value 源信號的內容
return [value length] > 5;
// 返回值 就是過濾條件。只有滿足這個條件才能獲取到內容
}] subscribeNext:^(id x) {
  NSLog(@"%@", x);
}];

skip跳過幾個信號

// skip:后邊傳入要跳過幾個信號
RACSubject *subject = [RACSubject subject];
[[subject skip:2] subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
[subject sendNext:@1];
[subject sendNext:@2];
[subject sendNext:@3];

distinctUntilChanged新值與舊值不一樣則接收

//例子1
RACSubject *subject = [RACSubject subject];
[[subject distinctUntilChanged] subscribeNext:^(id x) {
  NSLog(@"%@", x);
}];
// 發(fā)送信號
[subject sendNext:@1];
[subject sendNext:@2];
[subject sendNext:@2]; // 不會被訂閱
//例子2
[[RACObserve(self, title) distinctUntilChanged] subscribeNext:^(id x) {
        
}];

take只拿前幾個值

RACSubject *subject = [RACSubject subject];
[[subject take:2] subscribeNext:^(id x) {
  NSLog(@"%@", x);
}];
// 發(fā)送信號
[subject sendNext:@1];
[subject sendNext:@2];
[subject sendNext:@3];

takeLast取最后幾個值,takeLast 一定要調用sendCompleted,告訴他發(fā)送完成才能取到最后的幾個值

RACSubject *subject = [RACSubject subject];
[[subject takeLast:2] subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
// 發(fā)送信號
[subject sendNext:@1];
[subject sendNext:@2];
[subject sendNext:@3];
[subject sendCompleted];

takeUntil給takeUntil傳的是哪個信號,那么當這個信號發(fā)送信號或sendCompleted,就不能再接受源信號的內容了

RACSubject *subject = [RACSubject subject];
RACSubject *subject2 = [RACSubject subject];
[[subject takeUntil:subject2] subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
// 發(fā)送信號
[subject sendNext:@1];
[subject sendNext:@2];
[subject2 sendNext:@3];  // 1
//    [subject2 sendCompleted]; // 或2
[subject sendNext:@4];

ignore:忽略一些值
ignoreValues:表示忽略所有的值

// 1.創(chuàng)建信號
RACSubject *subject = [RACSubject subject];
// 2.忽略一些值
RACSignal *ignoreSignal = [subject ignore:@2]; // ignoreValues:表示忽略所有的值
// 3.訂閱信號
[ignoreSignal subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
// 4.發(fā)送數(shù)據(jù)
[subject sendNext:@2];

10.RAC組合

combine場景:賬號和密碼都有值,登錄按鈕才可點擊

//reduce里的參數(shù)一定要和combineLatest數(shù)組里的一一對應。
RACSignal *combinSignal = [RACSignal combineLatest:@[self.accountField.rac_textSignal, self.pwdField.rac_textSignal] reduce:^id(NSString *account, NSString *pwd){ NSLog(@"%@ %@", account, pwd);
  return @(account.length && pwd.length);
}];

RAC(self.loginBtn, enabled) = combinSignal;

merge多個信號合并成一個信號,任何一個信號有新值就會調用

// 創(chuàng)建信號A
RACSubject *signalA = [RACSubject subject];
// 創(chuàng)建信號B
RACSubject *signalB = [RACSubject subject];
//組合信號
RACSignal *mergeSignal = [signalA merge:signalB];
// 訂閱信號
[mergeSignal subscribeNext:^(id x) {
  NSLog(@"%@", x);
}];
// 發(fā)送信號---交換位置則數(shù)據(jù)結果順序也會交換
[signalB sendNext:@"下部分"];
[signalA sendNext:@"上部分"];

concat:串行執(zhí)行,第一個信號必須要調用sendCompleted

// 創(chuàng)建信號A
RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
  [subscriber sendNext:@"上部分數(shù)據(jù)"];
  [subscriber sendCompleted]; // 必須要調用sendCompleted方法!
  return nil;
}];

// 創(chuàng)建信號B,
RACSignal *signalsB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
  [subscriber sendNext:@"下部分數(shù)據(jù)"];
  return nil;
}];

// 創(chuàng)建組合信號
RACSignal *concatSignal = [signalA concat:signalsB];
// 訂閱組合信號
[concatSignal subscribeNext:^(id x) {
NSLog(@"%@",x);
}];

其他方法

doNext:添加額外執(zhí)行代碼

[[[self.button rac_signalForControlEvents:UIControlEventTouchUpInside] doNext:^(id x){
    //開始loading
}] subscribeNext:^(id x){
    //結束loading
}];
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • RAC使用測試Demo下載:github.com/FuWees/WPRACTestDemo 1.ReactiveC...
    FuWees閱讀 6,633評論 3 10
  • 前言 由于時間的問題,暫且只更新這么多了,后續(xù)還會持續(xù)更新本文《最快讓你上手ReactiveCocoa之進階篇》,...
    sumrain_cloud閱讀 1,308評論 0 0
  • 前言由于公司需使用RAC+MVVM模式要寫業(yè)務邏輯,對于rac菜雞的我,不得不補習下功課,在RAC中,萬物皆信號。...
    flowerflower閱讀 5,394評論 19 18
  • 前言 之前對RAC有了一個基本的認識,了解了它的作用,以及RAC的運行機制,我們知道只要是信號(RACSignal...
    大大盆子閱讀 4,597評論 0 11
  • 1.ReactiveCocoa常見操作方法介紹。 1.1 ReactiveCocoa操作須知 所有的信號(RACS...
    F麥子閱讀 558評論 0 0

友情鏈接更多精彩內容