ReactiveCocoa(RAC)

一、參考


二、常用 方便查找

2.1 UITextField實(shí)時(shí)搜索(throttle 節(jié)流)

這段代碼的意思是若0.3秒內(nèi)無新信號(hào)(tf無輸入),并且輸入框內(nèi)不為空那么將會(huì)執(zhí)行,這對(duì)服務(wù)器的壓力減少有巨大幫助同時(shí)提高了用戶體驗(yàn)

[[[[[[self.searchField.rac_textSignal throttle:0.3] distinctUntilChanged] ignore:@""] map:^id(id value) {
    
    //這里使用的是信號(hào)中的信號(hào)這個(gè)概念
    return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        
        //  network request
        
        //  這里可將請(qǐng)求到的信息發(fā)送出去
        
        [subscriber sendNext:value];
        
        [subscriber sendCompleted];
        
        return [RACDisposable disposableWithBlock:^{
            
            //  cancel request
            
            // 這里可以將取消請(qǐng)求寫在這里,若輸入框有新輸入信息那么將會(huì)發(fā)送一個(gè)新的請(qǐng)求,原來那個(gè)沒執(zhí)行完的請(qǐng)求將會(huì)執(zhí)行這個(gè)取消請(qǐng)求的代碼
            
        }];
    }];
    
}]switchToLatest] subscribeNext:^(id x) {
    
    //這里獲取信息
    
    
}];
<div id = 'jump'>2.2 RACSignal</div>
//創(chuàng)建信號(hào)  默認(rèn)一個(gè)信號(hào)都是冷信號(hào)
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
    
    [subscriber sendNext:@"signal"];
    [subscriber sendCompleted];
    
    return [RACDisposable disposableWithBlock:^{
       //信號(hào)釋放
    }];
}];


//訂閱信號(hào)  訂閱了這個(gè)信號(hào),這個(gè)信號(hào)才會(huì)變?yōu)闊嵝盘?hào)
[signal subscribeNext:^(id x) {
    NSLog(@"x == %@",x);
} error:^(NSError *error) {
    NSLog(@"error = %@",error);
} completed:^{
    NSLog(@"completed");
}];

控制臺(tái)輸出

2017-07-04 22:26:34.677 XXX[3314:53316] x == signal
2017-07-04 22:26:34.677 XXX[3314:53316] completed
2.3 map 和 FlatternMap 映射

1.FlatternMap中的Block返回信號(hào)。
2.Map中的Block返回對(duì)象
3.開發(fā)中,如果信號(hào)發(fā)出的值不是信號(hào),映射一般使用Map
4.開發(fā)中,如果信號(hào)發(fā)出的值是信號(hào),映射一般使用FlatternMap。

[[self.textField.rac_textSignal map:^id(id value) {
    
    return [NSString stringWithFormat:@"pre+%@",value];
    
}] subscribeNext:^(id x) {
    
    NSLog(@"x == %@",x);
    
}];

vs

[[self.textField.rac_textSignal flattenMap:^RACStream *(id value) {
    
    return [RACReturnSignal return:[NSString stringWithFormat:@"輸出:%@",value]];;
    
}] subscribeNext:^(id x) {
    
    NSLog(@"x == %@",x);
    
}];

控制臺(tái)輸出

2017-07-04 23:06:24.060 XXX[3796:69496] x == pre+f
2017-07-04 23:06:24.089 XXX[3796:69496] x == pre+fd
2.4 filter
[[self.textField.rac_textSignal filter:^BOOL(id value) {
   
    return [value length] > 3;
    
}] subscribeNext:^(id x) {
    
    NSLog(@"x == %@",x);
    
}];

控制臺(tái)輸出

2017-07-04 23:11:45.563 XXX[3884:71980] x == hell
2017-07-04 23:11:47.111 XXX[3884:71980] x == hello
2.5 take/takeLast/skip

take 獲取信號(hào)的意思
eg: take:2 意思是獲取前兩了信號(hào)

RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
    
    [subscriber sendNext:@"1"];
    [subscriber sendNext:@"2"];
    [subscriber sendNext:@"3"];
    [subscriber sendCompleted];
    
    return [RACDisposable disposableWithBlock:^{
        NSLog(@"信號(hào)釋放");
    }];
}];


[[signal take:2] subscribeNext:^(id x) {
    NSLog(@"x == %@",x);
}];

控制臺(tái)輸出

2017-07-05 11:24:11.908 XXX[9717:84530] x == 1
2017-07-05 11:24:11.909 XXX[9717:84530] x == 2
2017-07-05 11:24:11.909 XXX[9717:84530] 信號(hào)釋放

takeLast 是逆序獲取的意思
eg:takeLast:2 是獲取最后兩個(gè)信號(hào)的意思

[[signal takeLast:2] subscribeNext:^(id x) {
    NSLog(@"x == %@",x);
}];

控制臺(tái)輸出

2017-07-05 11:28:30.267 XXX[9839:87189] x == 2
2017-07-05 11:28:30.267 XXX[9839:87189] x == 3
2017-07-05 11:28:30.267 XXX[9839:87189] 信號(hào)釋放

skip 是跳過

eg: skip:2 是跳過前兩個(gè)信號(hào) 從第三個(gè)信號(hào)開始

[[signal skip:2] subscribeNext:^(id x) {
    NSLog(@"x == %@",x);
}];

控制臺(tái)輸出

2017-07-05 11:31:33.308 XXX[9915:88941] x == 3
2017-07-05 11:31:33.309 XXX[9915:88941] 信號(hào)釋放
2.6 distinctUntilChanged

distinctUntilChanged的作用是使RAC不會(huì)連續(xù)發(fā)送兩次相同的信號(hào)

RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
    
    [subscriber sendNext:@"1"];
    [subscriber sendNext:@"1"];
    [subscriber sendNext:@"2"];
    [subscriber sendNext:@"3"];
    [subscriber sendNext:@"1"];
    [subscriber sendCompleted];
    
    return [RACDisposable disposableWithBlock:^{
        NSLog(@"信號(hào)釋放");
    }];
}];


[[signal distinctUntilChanged] subscribeNext:^(id x) {
    NSLog(@"x == %@",x);
}];

控制臺(tái)輸出

2017-07-05 12:53:45.642 XXX[10766:118852] x == 1
2017-07-05 12:53:45.643 XXX[10766:118852] x == 2
2017-07-05 12:53:45.643 XXX[10766:118852] x == 3
2017-07-05 12:53:45.643 XXX[10766:118852] x == 1
2017-07-05 12:53:45.643 XXX[10766:118852] 信號(hào)釋放
2.7 ignore

ignore 忽略信號(hào),指定一個(gè)任意類型的量(可以是字符串,數(shù)組等),當(dāng)需要發(fā)送信號(hào)時(shí)講進(jìn)行判斷,若相同則該信號(hào)會(huì)被忽略發(fā)送。

RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
    
    [subscriber sendNext:@"1"];
    [subscriber sendNext:@"3"];
    [subscriber sendNext:@"1"];
    [subscriber sendCompleted];
    
    return [RACDisposable disposableWithBlock:^{
        NSLog(@"信號(hào)釋放");
    }];
}];


[[signal ignore:@"1"] subscribeNext:^(id x) {
    NSLog(@"x == %@",x);
}];

控制臺(tái)輸出

2017-07-05 12:57:46.111 XXX[10849:121171] x == 3
2017-07-05 12:57:46.111 XXX[10849:121171] 信號(hào)釋放

三、ReactiveCocoa操作方法之組合。

3.1 concat按一定順序拼接信號(hào),當(dāng)多個(gè)信號(hào)發(fā)出的時(shí)候,有順序的接收信號(hào)
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
    
    [subscriber sendNext:@"1"];
    [subscriber sendCompleted];
    
    return [RACDisposable disposableWithBlock:^{
        NSLog(@"信號(hào)釋放");
    }];
}];


RACSignal *signal2 = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
    
    [subscriber sendNext:@"2"];
    
    return [RACDisposable disposableWithBlock:^{
        NSLog(@"信號(hào)2釋放");
    }];
}];

// 把signalA拼接到signalB后,signalA發(fā)送完成,signalB才會(huì)被激活。
RACSignal *concatSignal = [signal concat:signal2];

// 注意:第一個(gè)信號(hào)必須發(fā)送完成,第二個(gè)信號(hào)才會(huì)被激活
[concatSignal subscribeNext:^(id x) {
    NSLog(@"x == %@",x);
}];
3.2 then用于連接兩個(gè)信號(hào),當(dāng)?shù)谝粋€(gè)信號(hào)完成,才會(huì)連接then返回的信號(hào)。
// then:用于連接兩個(gè)信號(hào),當(dāng)?shù)谝粋€(gè)信號(hào)完成,才會(huì)連接then返回的信號(hào)
// 注意使用then,之前信號(hào)的值會(huì)被忽略掉.
// 底層實(shí)現(xiàn):1、先過濾掉之前的信號(hào)發(fā)出的值。2.使用concat連接then返回的信號(hào)
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
    
    [subscriber sendNext:@"1"];
    [subscriber sendCompleted];
    
    return [RACDisposable disposableWithBlock:^{
        NSLog(@"信號(hào)釋放");
    }];
}];


[[signal then:^RACSignal *{
    
    return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        
        [subscriber sendNext:@"2"];
        
        return [RACDisposable disposableWithBlock:^{
            NSLog(@"信號(hào)2釋放");
        }];
    }];
    
}] subscribeNext:^(id x) {
    
    // 只能接收到第二個(gè)信號(hào)的值,也就是then返回信號(hào)的值
    NSLog(@"x == %@",x);
}];

控制臺(tái)輸出

2017-07-05 14:30:57.094 XXX[15627:177519] x == 2
2017-07-05 14:30:57.094 XXX[15627:177519] 信號(hào)釋放
2017-07-05 14:30:57.094 XXX[15627:177519] 信號(hào)2釋放
3.3 merge 把多個(gè)信號(hào)合并為一個(gè)信號(hào),任何一個(gè)信號(hào)有新值的時(shí)候就會(huì)調(diào)用
// merge:把多個(gè)信號(hào)合并成一個(gè)信號(hào)
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
    
    [subscriber sendNext:@"1"];
    [subscriber sendCompleted];
    
    return [RACDisposable disposableWithBlock:^{
        NSLog(@"信號(hào)釋放");
    }];
}];


RACSignal *signal2 = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
    
    [subscriber sendNext:@"2"];
    [subscriber sendCompleted];
    
    return [RACDisposable disposableWithBlock:^{
        NSLog(@"信號(hào)2釋放");
    }];
}];

// 合并信號(hào),任何一個(gè)信號(hào)發(fā)送數(shù)據(jù),都能監(jiān)聽到.
RACSignal *mergeSignal = [[signal delay:2] merge:signal2];

[mergeSignal subscribeNext:^(id x) {
    NSLog(@"x == %@",x);
}];

// 底層實(shí)現(xiàn):
// 1.合并信號(hào)被訂閱的時(shí)候,就會(huì)遍歷所有信號(hào),并且發(fā)出這些信號(hào)。
// 2.每發(fā)出一個(gè)信號(hào),這個(gè)信號(hào)就會(huì)被訂閱
// 3.也就是合并信號(hào)一被訂閱,就會(huì)訂閱里面所有的信號(hào)。
// 4.只要有一個(gè)信號(hào)被發(fā)出就會(huì)被監(jiān)聽。

控制臺(tái)輸出

2017-07-05 14:45:20.350 XXX[15843:184057] 信號(hào)釋放
2017-07-05 14:45:20.350 XXX[15843:184057] x == 2
2017-07-05 14:45:20.350 XXX[15843:184057] 信號(hào)2釋放
2017-07-05 14:45:22.350 XXX[15843:184057] x == 1
3.4 zipWith把兩個(gè)信號(hào)壓縮成一個(gè)信號(hào),只有當(dāng)兩個(gè)信號(hào)同時(shí)發(fā)出信號(hào)內(nèi)容時(shí),并且把兩個(gè)信號(hào)的內(nèi)容合并成一個(gè)元組,才會(huì)觸發(fā)壓縮流的next事件。
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
    
    [subscriber sendNext:@"1"];
    [subscriber sendCompleted];
    
    return [RACDisposable disposableWithBlock:^{
        NSLog(@"信號(hào)釋放");
    }];
}];


RACSignal *signal2 = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
    
    [subscriber sendNext:@"2"];
    [subscriber sendCompleted];
    
    return [RACDisposable disposableWithBlock:^{
        NSLog(@"信號(hào)2釋放");
    }];
}];

RACSignal *zipSignal = [signal zipWith:signal2];
[zipSignal subscribeNext:^(id x) {
    NSLog(@"x == %@",x);
}];

// 底層實(shí)現(xiàn):
// 1.定義壓縮信號(hào),內(nèi)部就會(huì)自動(dòng)訂閱signal,signal2
// 2.每當(dāng)signal或者signal2發(fā)出信號(hào),就會(huì)判斷signal,signal2有沒有發(fā)出個(gè)信號(hào),有就會(huì)把最近發(fā)出的信號(hào)都包裝成元組發(fā)出。

控制臺(tái)輸出

2017-07-05 15:33:29.336 XXX[16308:202275] 信號(hào)釋放
2017-07-05 15:33:29.337 XXX[16308:202275] x == <RACTuple: 0x608000003460> (
1,
2
)
2017-07-05 15:33:29.337 XXX[16308:202275] 信號(hào)2釋放
3.5 combineLatest將多個(gè)信號(hào)合并起來,并且拿到各個(gè)信號(hào)的最新的值,必須每個(gè)合并的signal至少都有過一次sendNext,才會(huì)觸發(fā)合并的信號(hào)。
RACSignal *combineSignal = [signal combineLatestWith:signal2];
[combineSignal subscribeNext:^(id x) {
    NSLog(@"x == %@",x);
}];

// 底層實(shí)現(xiàn):
// 1.當(dāng)組合信號(hào)被訂閱,內(nèi)部會(huì)自動(dòng)訂閱signal,signal2,必須兩個(gè)信號(hào)都發(fā)出內(nèi)容,才會(huì)被觸發(fā)。
// 2.并且把兩個(gè)信號(hào)組合成元組發(fā)出。

控制臺(tái)輸出 (和zipWith輸出一樣)

3.6 reduce聚合:用于信號(hào)發(fā)出的內(nèi)容是元組,把信號(hào)發(fā)出元組的值聚合成一個(gè)值
// 聚合
// 常見的用法,(先組合在聚合)。combineLatest:(id<NSFastEnumeration>)signals reduce:(id (^)())reduceBlock
// reduce中的block簡(jiǎn)介:
// reduceblcok中的參數(shù),有多少信號(hào)組合,reduceblcok就有多少參數(shù),每個(gè)參數(shù)就是之前信號(hào)發(fā)出的內(nèi)容
// reduceblcok的返回值:聚合信號(hào)之后的內(nèi)容。
RACSignal *reduceSignal = [RACSignal combineLatest:@[signal,signal2] reduce:^id (NSString *num1 ,NSString *num2){
    
    return [NSString stringWithFormat:@"%@ -> %@",num1,num2];

}];

[reduceSignal subscribeNext:^(id x) {
    NSLog(@"x == %@",x);
}];

// 底層實(shí)現(xiàn):
// 1.訂閱聚合信號(hào),每次有內(nèi)容發(fā)出,就會(huì)執(zhí)行reduceblcok,把信號(hào)內(nèi)容轉(zhuǎn)換成reduceblcok返回的值。

控制臺(tái)輸出

2017-07-05 15:50:18.815 XXX[16553:210326] 信號(hào)釋放
2017-07-05 15:50:18.816 XXX[16553:210326] x == 1 -> 2
2017-07-05 15:50:18.816 XXX[16553:210326] 信號(hào)2釋放

四、ReactiveCocoa操作方法之秩序。

  • doNext: 執(zhí)行Next之前,會(huì)先執(zhí)行這個(gè)Block
  • doCompleted: 執(zhí)行sendCompleted之前,會(huì)先執(zhí)行這個(gè)Block
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
    
    [subscriber sendNext:@"1"];
    [subscriber sendCompleted];
    
    return [RACDisposable disposableWithBlock:^{
        NSLog(@"信號(hào)釋放");
    }];
}];


[[[signal doNext:^(id x) {
    NSLog(@"執(zhí)行[subscriber sendNext:@\"1\"];之前會(huì)調(diào)用這個(gè)Block");
}] doCompleted:^{
    NSLog(@"執(zhí)行[subscriber sendCompleted];之前會(huì)調(diào)用這個(gè)Block");
}] subscribeNext:^(id x) {
    NSLog(@"x == %@",x);
}];

控制臺(tái)輸出

2017-07-05 15:58:44.053 XXX[16675:214218] 執(zhí)行[subscriber sendNext:@"1"];之前會(huì)調(diào)用這個(gè)Block
2017-07-05 15:58:44.054 XXX[16675:214218] x == 1
2017-07-05 15:58:44.055 XXX[16675:214218] 執(zhí)行[subscriber sendCompleted];之前會(huì)調(diào)用這個(gè)Block
2017-07-05 15:58:44.055 XXX[16675:214218] 信號(hào)釋放
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容