浅谈ReactCocoa与MVVN,MVC关系,及基本使用
简介
RAC全程ReactiveCocoa,是由Github开源的一个应用于iOS和OS开发的新框架。RAC结合了函数式编程(Functional Programming)和响应式编程(Reactive Programming),其中的函数式编程一直比较难以理解,最近在使用链式调用的过程当中,才获得进一步理解。
RAC5与其他版本区别 参考:http://blog.csdn.net/zhanglizhi111/article/details/73163676
浅谈MVVM的架构设计与团队协作 参考: http://www.cnblogs.com/ludashi/p/4211556.html
MVVN与MVC及OC传统项目理解
我个人对MVVM的理解主要是借鉴于之前浅尝VUE.js,MVVM就是基于数据绑定实现UI变化,通属来说即数据变,UI变; 而对于OC项目来说,由于苹果范例也是MVC为主,如果要实现MVVN必须复写数据绑定层,虽然最终会减轻C层代码量,但是最终还是会增加总代码量。由于最近重构信息流,我折中做了一种变种MVC专门针对处理,M层作为ViewModel(只传递数据,并且数据需要缓存),C层做为(只处理各种点击事件,控制器之间会用RAC作为解耦,另外,增加一个专做请求和各种数据排序和组合的请求层),V层(由一个专门根据ViewModel层做UI选择控制层,各种元件VIEW的组合)。 简而言之,就是MVC基础生,增加请求层和UI控制层。
//数据顺序 简图 可能描述会不够恰当
请求层请求数据(排序处理生成真实数据排序)-> C层 -> 通知V控制层处理UI变化->V控制层生成UI数据->C层按UI数据模型显示->C层事件->请求数据层再次请求数据->重复->重复->重复->重复->重复
pod安装
pod 'ReactiveObjC'
结合AFNWORKING使用
封装请求
/**
获取热点新闻列表
@param snapShotNumber snapShotNumber description
@param pageNum pageNum description
@return RACSignal object
*/
+ (RACSignal*)hotNews:(long long)snapShotNumber pageNum:(long long)pageNum{
return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
NSString* url = kURL(kHotNews);
NSMutableDictionary *paras = [NSMutableDictionary dictionary];
[paras setObject:@(snapShotNumber) forKey:@"snapShotNumber"];
[paras setObject:@(10) forKey:@"pageSize"];
[paras setObject:@(1) forKey:@"getPages"];
[paras setObject:@(pageNum) forKey:@"pageNum"];
NetworkOptionShareIntance.ttv_netWorkSericeType = TTVNetWorkPortNewsServiceType;
[TTVNetworkManager ttv_GET:url parameters:paras success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
[subscriber sendNext:responseObject];
[subscriber sendCompleted];
} failure:^(NSURLSessionDataTask * _Nullable task, TTVNetWorkError * _Nonnull error) {
[subscriber sendError:error];
[subscriber sendCompleted];
}];
return nil;
}];
}
使用封装
- (void)fetchDataWithLoadMore:(BOOL)loadmore handle:(void (^)(BOOL succ, NSInteger newsnum, BOOL showResultInfo))completion {
NSMutableArray* racList = [NSMutableArray array];
[racList addObject:[TTVApiService channelAdvertise:self.channID]];
[racList addObject:[TTVApiService hotNews:self.lastModel.snapShotNumber pageNum:self.pageNum + 1]];
RACSignal* combine = [RACSignal combineLatest:racList];
[combine subscribeNext:^(id _Nullable x) {
[self saveChannel];
NSArray* adList = [x objectAtIndex:0][@"adList"];
NSString* adHash = [x objectAtIndex:0][@"hash"];
NSDictionary *recvModelDic = [x objectAtIndex:1];
} error:^(NSError * _Nullable error) {
completion(NO, 0, YES);
}];
}
监控对象方法
UIViewController* vc = [TTVJumpManager jumpToMediaDetail:self newsDetailModel:newsModel pushModel:nil newsDataUpdateBlock:nil];
[[vc rac_signalForSelector:@selector(didMoveToParentViewController:)] subscribeNext:^(id _Nullable x) {
RACTupleUnpack(UINavigationController* navigationController) = x;
if (navigationController == nil) {
[self updateNavigationViewStatue];
}
}];
快捷处理RAC对象
//解包rac对象
RACTupleUnpack(UINavigationController* navigationController) = x;
//封包个对象成为rac对象
RACTuplePack(key, value);