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];
}
}];
}
网友评论