一直想寫篇關於RAC的文章,一是分享二是作爲筆記,因爲項目忙先簡單的貼一個本身當初學習的時候代碼吧數組
1、RACCommand網絡
// RACCommand 的使用: 使用場景,監聽按鈕點擊,網絡請求 - (void)RACCommand{ // 1.建立命令 RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) { NSLog(@"執行命令"); // 建立空信號,必須返回信號 // return [RACSignal empty]; // 2.建立信號,用來傳遞數據 return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { [subscriber sendNext:@"請求數據"]; // 注意:數據傳遞完,最好調用sendCompleted,這時命令才執行完畢。 [subscriber sendCompleted]; return nil; }]; }]; // 強引用命令,不要被銷燬,不然接收不到數據 self.conmmand = command; // 3.訂閱RACCommand中的信號 [command.executionSignals subscribeNext:^(id x) { NSLog(@"command.executionSignals %@",x); [x subscribeNext:^(NSString *x) { NSLog(@"x subscribeNext %@",x); }]; }]; // RAC高級用法 // switchToLatest:用於signal of signals,獲取signal of signals發出的最新信號,也就是能夠直接拿到RACCommand中的信號 // [command.executionSignals.switchToLatest subscribeNext:^(id x) { // // NSLog(@"command.executionSignals.switchToLatest %@",x); // }]; // 4.監聽命令是否執行完畢,默認會來一次,能夠直接跳過,skip表示跳過第一次信號。 [[command.executing skip:1] subscribeNext:^(id x) { if ([x boolValue] == YES) { // 正在執行 NSLog(@"正在執行"); }else{ // 執行完成 NSLog(@"執行完成"); } }]; // 5.執行命令 [self.conmmand execute:@1]; }
2、RACMulticastConnection學習
// RACMulticastConnection 使用場景:用於當一個信號,被屢次訂閱時,爲了保證建立信號時,避免屢次調用建立信號中的block,形成反作用,可使用這個類處理 - (void)RACMulticastConnection{ // 需求:假設在一個信號中發送請求,每次訂閱一次都會發送請求,這樣就會致使屢次請求。 // 解決:使用RACMulticastConnection就能解決. // 1.建立請求信號 // RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { // // // NSLog(@"發送請求"); // // return nil; // }]; // // 2.訂閱信號 // [signal subscribeNext:^(id x) { // // NSLog(@"接收數據"); // // }]; // // 2.訂閱信號 // [signal subscribeNext:^(id x) { // // NSLog(@"接收數據"); // // }]; // // 3.運行結果,會執行兩遍發送請求,也就是每次訂閱都會發送一次請求 // RACMulticastConnection:解決重複請求問題 // 1.建立信號 RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { NSLog(@"發送請求"); [subscriber sendNext:@1]; return nil; }]; // 2.建立鏈接 RACMulticastConnection *connect = [signal publish]; // 3.訂閱信號, // 注意:訂閱信號,也不能激活信號,只是保存訂閱者到數組,必須經過鏈接,當調用鏈接,就會一次性調用全部訂閱者的sendNext: [connect.signal subscribeNext:^(id x) { NSLog(@"訂閱者一信號 %@",x); }]; [connect.signal subscribeNext:^(id x) { NSLog(@"訂閱者二信號 %@",x); }]; // 4.鏈接,激活信號 [connect connect]; }
3、bindorm
// ReactiveCocoa核心方法bind - (void)bind{ // 假設想監聽文本框的內容,而且在每次輸出結果的時候,都在文本框的內容拼接一段文字「輸出:」 // 方式一:在返回結果後,拼接。 [self.textField.rac_textSignal subscribeNext:^(id x) { NSLog(@"輸出:%@",x); }]; // map [[_textField.rac_textSignal map:^id(id value) { // 當源信號發出,就會調用這個block,修改源信號的內容 // 返回值:就是處理完源信號的內容。 return [NSString stringWithFormat:@"輸出:%@",value]; }] subscribeNext:^(id x) { NSLog(@"%@",x); }]; }
4、concatblog
// 操做方法組合 - (void)concat{ RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { [subscriber sendNext:@1]; [subscriber sendCompleted]; return nil; }]; RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { [subscriber sendNext:@2]; return nil; }]; // 把signalA拼接到signalB後,signalA發送完成,signalB纔會被激活。 RACSignal *concatSignal = [signalA concat:signalB]; // 之後只須要面對拼接信號開發。 // 訂閱拼接的信號,不須要單獨訂閱signalA,signalB // 內部會自動訂閱。 // 注意:第一個信號必須發送完成,第二個信號纔會被激活 [concatSignal subscribeNext:^(id x) { NSLog(@"%@",x); }]; // concat底層實現: // 1.當拼接信號被訂閱,就會調用拼接信號的didSubscribe // 2.didSubscribe中,會先訂閱第一個源信號(signalA) // 3.會執行第一個源信號(signalA)的didSubscribe // 4.第一個源信號(signalA)didSubscribe中發送值,就會調用第一個源信號(signalA)訂閱者的nextBlock,經過拼接信號的訂閱者把值發送出來. // 5.第一個源信號(signalA)didSubscribe中發送完成,就會調用第一個源信號(signalA)訂閱者的completedBlock,訂閱第二個源信號(signalB)這時候才激活(signalB)。 // 6.訂閱第二個源信號(signalB),執行第二個源信號(signalB)的didSubscribe // 7.第二個源信號(signalA)didSubscribe中發送值,就會經過拼接信號的訂閱者把值發送出來. }
5、than事件
- (void)than{ // then:用於鏈接兩個信號,當第一個信號完成,纔會鏈接then返回的信號 // 注意使用then,以前信號的值會被忽略掉. // 底層實現:一、先過濾掉以前的信號發出的值。2.使用concat鏈接then返回的信號 [[[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { [subscriber sendNext:@1]; [subscriber sendCompleted]; return nil; }] then:^RACSignal *{ return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { [subscriber sendNext:@2]; return nil; }]; }] subscribeNext:^(id x) { // 只能接收到第二個信號的值,也就是then返回信號的值 NSLog(@"%@",x); }]; }
6、mergeip
- (void)merge{ // merge:把多個信號合併成一個信號 //建立多個信號 RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { [subscriber sendNext:@1]; return nil; }]; RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { [subscriber sendNext:@2]; return nil; }]; // 合併信號,任何一個信號發送數據,都能監聽到. RACSignal *mergeSignal = [signalA merge:signalB]; [mergeSignal subscribeNext:^(id x) { NSLog(@"%@",x); }]; // 底層實現: // 1.合併信號被訂閱的時候,就會遍歷全部信號,而且發出這些信號。 // 2.每發出一個信號,這個信號就會被訂閱 // 3.也就是合併信號一被訂閱,就會訂閱裏面全部的信號。 // 4.只要有一個信號被髮出就會被監聽。 }
7、zipWith開發
- (void)zipWith{ //zipWith:把兩個信號壓縮成一個信號,只有當兩個信號同時發出信號內容時,而且把兩個信號的內容合併成一個元組,纔會觸發壓縮流的next事件。 RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { [subscriber sendNext:@1]; return nil; }]; RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { [subscriber sendNext:@2]; return nil; }]; // 壓縮信號A,信號B RACSignal *zipSignal = [signalA zipWith:signalB]; [zipSignal subscribeNext:^(id x) { NSLog(@"%@",x); }]; // 底層實現: // 1.定義壓縮信號,內部就會自動訂閱signalA,signalB // 2.每當signalA或者signalB發出信號,就會判斷signalA,signalB有沒有發出個信號,有就會把最近發出的信號都包裝成元組發出。 }
8、combineLatestinput
// combineLatest:將多個信號合併起來,而且拿到各個信號的最新的值,必須每一個合併的signal至少都有過一次sendNext,纔會觸發合併的信號。 - (void)combineLatest{ RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { [subscriber sendNext:@1]; return nil; }]; RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { [subscriber sendNext:@2]; return nil; }]; // 把兩個信號組合成一個信號,跟zip同樣,沒什麼區別 RACSignal *combineSignal = [signalA combineLatestWith:signalB]; [combineSignal subscribeNext:^(id x) { NSLog(@"%@",x); }]; // 底層實現: // 1.當組合信號被訂閱,內部會自動訂閱signalA,signalB,必須兩個信號都發出內容,纔會被觸發。 // 2.而且把兩個信號組合成元組發出。 }
9、combineLatestReducestring
// 組合並聚合 - (void)combineLatestReduce{ RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { [subscriber sendNext:@1]; return nil; }]; RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { [subscriber sendNext:@2]; return nil; }]; // 聚合 // 常見的用法,(先組合在聚合)。combineLatest:(id<NSFastEnumeration>)signals reduce:(id (^)())reduceBlock // reduce中的block簡介: // reduceblcok中的參數,有多少信號組合,reduceblcok就有多少參數,每一個參數就是以前信號發出的內容 // reduceblcok的返回值:聚合信號以後的內容。 RACSignal *reduceSignal = [RACSignal combineLatest:@[signalA,signalB] reduce:^id(NSNumber *num1 ,NSNumber *num2){ return [NSString stringWithFormat:@"%@ %@",num1,num2]; }]; [reduceSignal subscribeNext:^(id x) { NSLog(@"%@",x); }]; // 底層實現: // 1.訂閱聚合信號,每次有內容發出,就會執行reduceblcok,把信號內容轉換成reduceblcok返回的值。 }