RACCommand
RACCommand的普通使用
一般情況下,RACCommand主要用來封裝一些請求,事件等,舉個例子,我們的tableView在下拉滾動時若想刷新數(shù)據(jù)需要向接口提供頁碼或者最后一個數(shù)據(jù)的ID,我們可以把請求封裝進RACCommand里,想要獲取數(shù)據(jù)的時候只要將頁碼或者ID傳入RACCommand里就可以了,同時監(jiān)控RACCommand何時完成,若完成后將數(shù)據(jù)加入到tableview的數(shù)組就可以了,這是一個平常用的比較多的場景.使用是主要有三個注意點
RACCommand必須返回信號,信號可以為空
RACCommand必須強引用
RACCommand發(fā)送完數(shù)據(jù)必須發(fā)送完成信號
-
在viewModel中創(chuàng)建RACCommand,同時利用懶加載,在外界獲取command的時候,直接執(zhí)行下面這個方法
-(void)loadInfo{ //input就是控制器中,viewmodel執(zhí)行command時excute傳入的參數(shù) RACCommand * command = [[RACCommand alloc]initWithSignalBlock:^RACSignal *(id input) { //command必須有信號返回值,如果沒有的話可以為[RACSignal empty] return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { NSMutableDictionary * params = [NSMutableDictionary dictionary]; params[@"build"] = @"3360"; params[@"channel"] = @"appstore"; params[@"plat"] = @"2"; [FYRequestTool GET:@"http://app.bilibili.com/x/banner" parameters:params progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { [subscriber sendNext:responseObject]; //發(fā)送完信號必須發(fā)送完成信號,否則無法執(zhí)行 [subscriber sendCompleted]; } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { [subscriber sendError:error]; }]; return [RACDisposable disposableWithBlock:^{ [FYRequestTool cancel]; NSLog(@"這里面可以寫取消請求,完成信號后請求會取消"); }]; }]; }]; //必須強引用這個command,否則無法執(zhí)行 self.command = command; } -
在控制器端取到viewModel模型,并對command中帶有數(shù)據(jù)的信號進行訂閱,這里需要明白信號中的信號這個含義,RAC中最基礎的就是信號,command也是一個信號,與signal不同的是,它返回的并不是數(shù)據(jù)而是一個信號,這個信號上帶有數(shù)據(jù)
ViewModel * vm = [[ViewModel alloc]init]; //取到command信號中的信號,對其進行訂閱 [vm.command.executionSignals.switchToLatest subscribeNext:^(id x) { NSLog(@"%@",x); } error:^(NSError *error) { NSLog(@"%@",error); } completed:^{ NSLog(@"完成"); }]; //必須要加這句話,否則command無法執(zhí)行,excute傳的參數(shù)若無用可以為nil,傳的參數(shù)就是viewModel中RACCommand中block的input值,根據(jù)這個值我們可以做許多事情 //例如,封裝一個tableview的翻頁請求,每次翻頁的時候可以通過excute把翻頁的頁碼給他 [vm.command execute:nil]; -
我們再來看一下RACCommand直接進行訂閱是什么結果
//取到command信號 [vm.command.executionSignals subscribeNext:^(id x) { NSLog(@"-------------------------%@",[x class]); NSLog(@"這里獲取到的x是一個帶有數(shù)據(jù)的信號,需要對x做進一步訂閱就可以獲取到數(shù)據(jù)如上所示"); }]; -
打印結果是
2016-08-23 18:13:42.437 the basis of RACCommand[10910:768132] -------------------------RACDynamicSignal 2016-08-23 18:13:42.437 the basis of RACCommand[10910:768132] 這里獲取到的x是一個帶有數(shù)據(jù)的信號,需要對x做進一步訂閱就可以獲取到數(shù)據(jù)如上所示
由此可知RACCommand也是一個信號
監(jiān)聽RACCommand是否完成
-原理很簡單,還是利用的信號中的信號這一理念
//監(jiān)聽命令是否完成
[vm.command.executing subscribeNext:^(id x) {
//這里的x是一個帶有數(shù)據(jù)的信號,若這個信號存在那么就說明command還在執(zhí)行,否則說明沒有執(zhí)行或者執(zhí)行完畢
if ([x boolValue]) {
NSLog(@"正在執(zhí)行");
} else {
NSLog(@"執(zhí)行未開始/執(zhí)行完畢");
}
}];