map -- 映射
創(chuàng)建一個訂閱者的映射并且返回數(shù)據(jù)(例:將textField的字符串轉(zhuǎn)為其本身長度)
[[self.textField.rac_textSignal map:^id(NSString *value) {
NSLog(@"%@", value);
return value.length;
}] subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
flattenmap -- 扁平映射(信號中的信號)
實際上是根據(jù)前一個信號傳遞進(jìn)來的參數(shù)重新建立了一個信號,這個參數(shù),可能會在創(chuàng)建信號的時候用到,也有可能根本用不到
- (RACSignal *)signInSignal {
return [RACSignal createSignal:^RACDisposable *(id subscriber){
[self.signInService
signInWithUsername:self.usernameTextField.text
password:self.passwordTextField.text
complete:^(BOOL success){
[subscriber sendNext:@(success)];
[subscriber sendCompleted];
}];
return nil;
}];
}
[[[self.signInButton
rac_signalForControlEvents:UIControlEventTouchUpInside]
map:^id(id x){
return [self signInSignal];
}]
subscribeNext:^(id x){
NSLog(@"Sign in result: %@", x);
}];
此時當(dāng)我們使用map映射的是一個信號(即信號中的信號),映射出來的value是(RACSignal *),這時我們subscribeNext的value即為此信號類型,而不是信號中的value值;所以這里調(diào)用flattenMap,創(chuàng)建新的信號,使用(RACSignal *)的value作為新信號的value,也就是我們需要的值。
補充
map 與 swtichToLatest結(jié)合類似于flattenMap
switchToLatest:選擇最新的信號的value,比如我依次發(fā)送3個signal,但是switchToLatest只取第三個響應(yīng)信號的value。
filter -- 過濾
信號變化時篩選出需要的信號(例:當(dāng)textField的字符串長度大于3時,信號才會響應(yīng))
[[self.textField.rac_textSignal filter:^BOOL(NSString *value) {
return value.length > 3;
}] subscribeNext:^(id x) {
NSLog(@"x = %@", x);
}];
take/skip/repeat -- 獲取/跳過/重復(fù)
RACSignal *signal = [[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@"1"];
[subscriber sendNext:@"2"];
[subscriber sendNext:@"3"];
[subscriber sendNext:@"4"];
[subscriber sendNext:@"5"];
[subscriber sendCompleted];
return nil;
}] take:2];
[signal subscribeNext:^(id x) {
NSLog(@"%@", x);
}completed:^{
NSLog(@"completed");
}];
這個signal只會輸出前兩個信號1和2還有完成信號completed,skip repeat同理。
相似的還有takeLast takeUntil takeWhileBlock skipWhileBlock skipUntilBlock repeatWhileBlock都可以根據(jù)字面意思來理解。
distinctUntilChanged
網(wǎng)絡(luò)請求中為了減輕服務(wù)器壓力,無用的請求我們應(yīng)該盡可能不發(fā)送。distinctUntilChanged的作用是使RAC不會連續(xù)發(fā)送兩次相同的信號,這樣就解決了這個問題。
[[[self.textField rac_textSignal] distinctUntilChanged] subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
ignore -- 忽略
指定一個任意類型的量(可以是字符串,數(shù)組等),當(dāng)需要發(fā)送信號時講進(jìn)行判斷,若相同則該信號會被忽略發(fā)送。
[[[self.textFild rac_textSignal] ignore:@"good"] subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
delay -- 延時
RACSignal *signal = [[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@"delay"];
[subscriber sendCompleted];
return nil;
}] delay:2];
NSLog(@"tag");
[signal subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
throttle --節(jié)流
在我們做搜索框的時候,有時候需求的時實時搜索,即用戶每每輸入字符,view都要求展現(xiàn)搜索結(jié)果。這時如果用戶搜索的字符串較長,那么由于網(wǎng)絡(luò)請求的延時可能造成UI顯示錯誤,并且多次不必要的請求還會加大服務(wù)器的壓力,這顯然是不合理的,此時我們就需要用到節(jié)流。
[[[self.textFild rac_textSignal] throttle:0.5] subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
加了節(jié)流管道,后面跟上了類型為NSTimeInterval的參數(shù)后,只有0.5S內(nèi)信號不產(chǎn)生變化才會發(fā)送請求,這樣快速的輸入也不會造成多次輸出。
timeout -- 超時信號
當(dāng)超出限定時間后會給訂閱者發(fā)送error信號。
RACSignal *signal = [[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[[RACScheduler mainThreadScheduler] afterDelay:3 schedule:^{
[subscriber sendNext:@"delay"];
[subscriber sendCompleted];
}];
return nil;
}] timeout:2 onScheduler:[RACScheduler mainThreadScheduler]];
[signal subscribeNext:^(id x) {
NSLog(@"%@", x);
} error:^(NSError *error) {
NSLog(@"%@", error);
}];
由于在創(chuàng)建信號是限定了延遲3秒發(fā)送,但是加了timeout2秒的限定,所以這一定是一個超時信號。這個信號被訂閱后,由于超時,不會執(zhí)行訂閱成功的輸出x方法,而是跳到error的塊輸出了錯誤信息。timeout在用RAC封裝網(wǎng)絡(luò)請求時可以節(jié)省不少的代碼量。