MVVM在iOS中的使用

1.理解:

MVVM是一种设计模式,本质在于ViewModel与View或Controller层进行绑定,model层数据变化可以通过ViewModel直接更新UI。

开发过程中,从可读性和开发效率上简单的视图倾向于Controller持有特定的ViewModel。

2.优势

(1)简化开发

一个Controller针对某一任务持有其ViewModel,而非View或者subView持有,只需要维护Controller这一层的ViewModel;

(2)解耦

让View专注于视图和视图逻辑,ViewModel专注于逻辑处理、网络请求、数据解析以及暴露数据接口;

(3)便于测试,高复用性

View和ViewModel由于低耦合性,可以方便被其它模块调用。ViewModel可以单独调试。

3.使用场景

场景:博文列表

属性 类型
authorLabel作者 UILabel
avatarImgView头像 UIImageView
contentLabel博文 UILabel

Cell层,提供外部访问的组件

@interface BlogCell : TYBaseTableViewCell

/// 作者
@property (nonatomic, strong) UILabel *authorLabel;

/// 头像
@property (nonatomic, strong) UIImageView *avatarImgView;

/// 博文
@property (nonatomic, strong) UILabel *contentLabel;

@end

ViewModel层,提供数据源,提供方式给C层Subscribe,从而刷新数据,以下提供3种方式状态值,RACSubject,RACCommand

@interface BlogViewModel : NSObject

/// 数据源
@property (nonatomic, strong) NSMutableArray *dataArray;

/// 状态:刷新状态
@property (nonatomic, assign) TYStatus status;

/// 单向
@property (nonatomic, strong) RACSubject *subject;

/// 双向
@property (nonatomic, strong) RACCommand *command;

@end

Controller层,视图的配置和初始化等,主要有3块:1、cell的赋值 2、UI逻辑下拉刷新 3、UI逻辑加载更多

    // Cell的配置和赋值
    [listView setConfigCellBlock:^UITableViewCell * _Nonnull(UITableView * _Nonnull table, NSIndexPath * _Nonnull indexPath) {
        BlogCell *cell = [table dequeueReusableCellWithIdentifier:NSStringFromClass([BlogCell class])];
        if (indexPath.row < weakSelf.blogVM.dataArray.count) {
            id info = weakSelf.blogVM.dataArray[indexPath.row];
            cell.avatarImgView.image = [UIImage imageNamed:info[@"avatar"]];
            cell.authorLabel.text    = info[@"author"];
            cell.contentLabel.text   = info[@"content"];
        }
        return cell;
    }];
    // 刷新
    [listView setRefreshBlock:^{
        [weakSelf request];
    }];
    // 加载更多
    [listView setLoadMoreBlock:^{
        [weakSelf loadMore];
    }];

Controller层,绑定ViewModel和更新View,以下提供2种方式,RACSubject和自定义状态

- (void)bind {
    @weakify(self);
    [self.blogVM.subject subscribeNext:^(id  _Nullable x) {
            // ....
    }];

    [RACObserve(self.blogVM, status)subscribeNext:^(id  _Nullable x) {
        @strongify(self);
        NSInteger val = [x integerValue];
        if (val == TYStatusRefreshCompleted) {
            [self.listView endRefresh];
            [self.listView reloadData];
        }
        else if (val == TYStatusLoadCompleted) {
            [self.listView endLoadingMore];
            [self.listView reloadData];
        }
    }];
}

你可能感兴趣的:(MVVM在iOS中的使用)