简介

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);