從數(shù)據(jù)生產(chǎn)與消費(fèi)的角度理解RACSignal
在ReactiveCocoa框架的世界里,接觸到最多的最常見的類就是RACSignal
玄柠,凡是接觸過ReactiveCocoa的程序員休涤,都或多或少咱圆,以直接或間接的方式與RACSignal打過交道。
但是每當(dāng)提及RACSignal
是什么功氨,以及為什么要使用它時(shí)序苏,總是感覺一知半解,說不知道吧也知道點(diǎn)兒捷凄,說知道吧又不是很清楚忱详,試圖回答時(shí)卻感覺沒有回答到要點(diǎn)上。下文中我試圖談一下我自己的理解跺涤。
首先拋出一個(gè)觀點(diǎn):我們編寫的程序匈睁,無論是前端還是后端,都是圍繞著處理數(shù)據(jù)展開的钦铁,其次在處理數(shù)據(jù)之前软舌,我們必須能夠獲取到數(shù)據(jù)。
我們按職責(zé)劃分牛曹,將數(shù)據(jù)處理模塊劃分為兩個(gè)模塊佛点,需要使用數(shù)據(jù)的模塊稱為數(shù)據(jù)消費(fèi)者,提供數(shù)據(jù)的稱為數(shù)據(jù)生產(chǎn)者黎比。二者的關(guān)系為:數(shù)據(jù)消費(fèi)者通過調(diào)用數(shù)據(jù)生產(chǎn)者來獲取自己需要的數(shù)據(jù)超营,在這個(gè)過程中,二者各需要關(guān)注以下幾點(diǎn):
數(shù)據(jù)生產(chǎn)者
- 以何種方式封裝數(shù)據(jù)生產(chǎn)過程阅虫?
- 數(shù)據(jù)生產(chǎn)完成以后演闭,以何種機(jī)制提供給數(shù)據(jù)消費(fèi)者使用?
數(shù)據(jù)消費(fèi)者
- 如何觸發(fā)數(shù)據(jù)獲取過程颓帝?
- 如何獲取到來自生產(chǎn)者提供的數(shù)據(jù)米碰?
數(shù)據(jù)生產(chǎn)者
在ReactiveCocoa框架的世界中,RACSignal扮演的就是數(shù)據(jù)生產(chǎn)者的角色购城。因此RACSignal必須滿足上述數(shù)據(jù)生產(chǎn)者的兩個(gè)基本需求吕座,這是其職責(zé)所在。下面就具體以RACSignal為例瘪板,闡明其是如何滿足上述兩個(gè)基本需求的吴趴。
RACSignal是如何封裝數(shù)據(jù)生產(chǎn)過程的?
RACSignal的+createSignal:
方法接收一個(gè)block作為參數(shù)侮攀,該block定義了數(shù)據(jù)的生產(chǎn)過程锣枝。比如下面的例子厢拭,+createSignal:
方法的參數(shù)傳了了一個(gè)block,此block中封裝了賬戶登錄網(wǎng)絡(luò)請(qǐng)求的過程撇叁。
- (RACSignal *)signInSignal {
return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[self.signInService
signInWithUsername:self.usernameTextField.text
password:self.passwordTextField.text
complete:^(BOOL success) {
[subscriber sendNext:@(success)];
[subscriber sendCompleted];
}];
return nil;
}];
}
RACSignal以何種方式將其生產(chǎn)的數(shù)據(jù)發(fā)送給數(shù)據(jù)消費(fèi)者使用供鸠?
RACSignal的實(shí)例是一個(gè)對(duì)象,該對(duì)象支持訂閱陨闹,數(shù)據(jù)消費(fèi)者以訂閱該對(duì)象的形式獲取到生產(chǎn)的數(shù)據(jù)并使用回季。比如下面的例子,數(shù)據(jù)消費(fèi)者創(chuàng)建了一個(gè)RACSignal的對(duì)象signInSignal
正林,隨后通過-subscribeNext:
方法訂閱該對(duì)象,獲取數(shù)據(jù)颤殴。
- (void)signInButton {
RACSignal *signInSignal = [self signInSignal];
[signInSignal subscribeNext:^(id x) {
NSLog(@"Sign in result: %@", x);
}];
}
RACSignal是以發(fā)布-訂閱的模式來進(jìn)行通信的觅廓,而不是以直接通信的方式發(fā)送給數(shù)據(jù)使用者的。
數(shù)據(jù)消費(fèi)者
數(shù)據(jù)消費(fèi)者一般是我們程序中的對(duì)象涵但,NSObject或其子類的一個(gè)實(shí)例杈绸,比如UIViewController的實(shí)例。
數(shù)據(jù)消費(fèi)者以何種方式觸發(fā)數(shù)據(jù)獲取流程矮瘟?
數(shù)據(jù)獲取流程會(huì)在訂閱發(fā)生時(shí)自動(dòng)觸發(fā)瞳脓。比如下面的例子,當(dāng)調(diào)用signInSignal
的-subscribeNext:
方法時(shí)澈侠,在+createSignal:
階段傳入的block(該block里面的代碼就是獲取數(shù)據(jù)流程)就會(huì)執(zhí)行劫侧,從而觸發(fā)登錄請(qǐng)求的執(zhí)行。
- (void)signInButton {
RACSignal *signInSignal = [self signInSignal];
[signInSignal subscribeNext:^(id x) {
NSLog(@"Sign in result: %@", x);
}];
}
如何獲取到數(shù)據(jù)生產(chǎn)者提供給自己的數(shù)據(jù)哨啃?
-subscribeNext:
方法的參數(shù)是一個(gè)block烧栋,該block有一個(gè)id類型的參數(shù)x,正是通過該參數(shù)拳球,數(shù)據(jù)消費(fèi)者拿到來自數(shù)據(jù)生產(chǎn)者的數(shù)據(jù)并使用审姓。
結(jié)語
RACSignal是一個(gè)類,該類封裝了數(shù)據(jù)獲取過程祝峻,并提供一種數(shù)據(jù)使用機(jī)制魔吐。