RACCommand作為ReactiveCocoa基本組件之一,通常在項(xiàng)目開(kāi)發(fā)過(guò)程中RACSignal與RACSubject組合使用就可以滿(mǎn)足大部分的開(kāi)發(fā)需求。
RACCommand個(gè)人理解為事件響應(yīng)信號(hào)的管理者。其本身并不繼承自RACSignal或者RACStream類(lèi),而是繼承于NSObject,用于管理RACSignal類(lèi)的創(chuàng)建于訂閱的類(lèi)。關(guān)于RACCommand類(lèi)的作用,找到了一篇國(guó)外的博客原文鏈接,其中寫(xiě)道:

大意為,RACCommand類(lèi)用于響應(yīng)動(dòng)作事件的執(zhí)行,執(zhí)行命令通常由用戶(hù)交互頁(yè)面的手勢(shì)操作來(lái)觸發(fā)。該類(lèi)可以實(shí)現(xiàn)多種不同情況下的響應(yīng)事件處理,除了可以快速綁定交互頁(yè)面,還可以確保其在未使用時(shí)不會(huì)執(zhí)行信號(hào)操作。
因此在實(shí)際項(xiàng)目開(kāi)發(fā)中,RACCommand使用的場(chǎng)景多用于交互手勢(shì)操作響應(yīng)事件,以及網(wǎng)絡(luò)請(qǐng)求時(shí)不同請(qǐng)求狀態(tài)的處理封裝處理。當(dāng)需要響應(yīng)事件或網(wǎng)絡(luò)請(qǐng)求時(shí),直接執(zhí)行對(duì)應(yīng)RACCommand就可以發(fā)送信號(hào),執(zhí)行操作。當(dāng)RACCommand內(nèi)部收到請(qǐng)求時(shí),把處理的結(jié)果返回給外部,這時(shí)要通過(guò)signalBlock返回的信號(hào)進(jìn)行數(shù)據(jù)傳遞。
接下來(lái),看看RACCommand類(lèi)的基本使用
//創(chuàng)建command信號(hào)
RACCommand *command = [[RACCommand alloc]initWithSignalBlock:^RACSignal * _Nonnull(id _Nullable input) {
//返回RACSignal信號(hào)類(lèi)型對(duì)象
return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
[subscriber sendNext:@"this is signal of command"];
NSError *error = [NSError errorWithDomain:NSCocoaErrorDomain code:1234 userInfo:@{@"key":@"error"}];
[subscriber sendError:error];
return [RACDisposable disposableWithBlock:^{
NSLog(@"銷(xiāo)毀了");
}];
}];
}];
//command信號(hào)是否正在執(zhí)行
[command.executing subscribeNext:^(NSNumber * _Nullable x) {
NSLog(@"executing == %@",x);
}];
//錯(cuò)誤信號(hào)
[command.errors subscribeNext:^(NSError * _Nullable x) {
NSLog(@"errors == %@",x);
}];
//command信號(hào)中的signal信號(hào)發(fā)送出來(lái)的訂閱信號(hào)
[command.executionSignals subscribeNext:^(id _Nullable x) {
NSLog(@"executionSignals == %@",x);
}];
//必須執(zhí)行命令,否則所有信號(hào)都不會(huì)訂閱到
[command execute:@"command執(zhí)行"];

從打印結(jié)果中可以發(fā)現(xiàn),executing屬性在信號(hào)開(kāi)始時(shí),一定會(huì)返回0,代表RACCommand未執(zhí)行,在實(shí)際應(yīng)用中,并不需要監(jiān)聽(tīng)command第一次未執(zhí)行狀態(tài)。此處可將屬性executing的代碼修改成自動(dòng)跳過(guò)第一個(gè)信號(hào)
[[command.executing skip:1] subscribeNext:^(NSNumber * _Nullable x) {
NSLog(@"executing == %@",x);
}];
打印結(jié)果中,已經(jīng)打印出command中的RACSignal信號(hào),若需要監(jiān)聽(tīng)發(fā)送信號(hào)中的具體內(nèi)容,可將executionSignals的訂閱信號(hào)代碼修改成:
//監(jiān)聽(tīng)最后一次發(fā)送的信號(hào)
[[command.executionSignals switchToLatest] subscribeNext:^(id _Nullable x) {
NSLog(@"executionSignals == %@",x);
}];
這時(shí)的打印結(jié)果就變成了預(yù)期想要的結(jié)果

至于為什么error信號(hào),沒(méi)有被executionSignals訂閱到,而是被errors給訂閱到了?
原因在于這個(gè)errors是一個(gè)被包裝在RACSignal信號(hào)類(lèi)對(duì)象,進(jìn)行錯(cuò)誤處理的時(shí)候,我們不應(yīng)該使用subscribeError:對(duì)RACCommand的executionSignals
進(jìn)行錯(cuò)誤的訂閱,因?yàn)閑xecutionSignals這個(gè)信號(hào)是不會(huì)發(fā)送error事件的,而應(yīng)該使用subscribeNext:去訂閱錯(cuò)誤信號(hào)。

在RACCommand使用中,創(chuàng)建的RACSignal信號(hào)時(shí),發(fā)送完訂閱信號(hào)時(shí),若沒(méi)有error信號(hào)發(fā)送,則需要執(zhí)行[subscriber sendCompleted]命令來(lái)銷(xiāo)毀信號(hào)。否則該RACCommand會(huì)一直處于執(zhí)行狀態(tài)而無(wú)法正常釋放。
接下來(lái)以一個(gè)簡(jiǎn)單的登錄頁(yè)面小demo來(lái)介紹RACCommand的作用與使用方法。
GitHub鏈接demo鏈接
該文章首次發(fā)表在 簡(jiǎn)書(shū):我只不過(guò)是出來(lái)寫(xiě)寫(xiě)代碼 博客,并自動(dòng)同步至 騰訊云:我只不過(guò)是出來(lái)寫(xiě)寫(xiě)iOS 博客