1.理解:
MVVM是一種設(shè)計(jì)模式,本質(zhì)在于ViewModel與View或Controller層進(jìn)行綁定,model層數(shù)據(jù)變化可以通過ViewModel直接更新UI。
開發(fā)過程中,從可讀性和開發(fā)效率上簡單的視圖傾向于Controller持有特定的ViewModel。
2.優(yōu)勢(shì)
(1)簡化開發(fā)
一個(gè)Controller針對(duì)某一任務(wù)持有其ViewModel蔫慧,而非View或者subView持有,只需要維護(hù)Controller這一層的ViewModel权薯;
(2)解耦
讓View專注于視圖和視圖邏輯姑躲,ViewModel專注于邏輯處理、網(wǎng)絡(luò)請(qǐng)求崭闲、數(shù)據(jù)解析以及暴露數(shù)據(jù)接口肋联;
(3)便于測(cè)試,高復(fù)用性
View和ViewModel由于低耦合性刁俭,可以方便被其它模塊調(diào)用。ViewModel可以單獨(dú)調(diào)試韧涨。
3.使用場(chǎng)景
場(chǎng)景:博文列表
屬性 | 類型 |
---|---|
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層,提供數(shù)據(jù)源虑粥,提供方式給C層Subscribe如孝,從而刷新數(shù)據(jù),以下提供3種方式狀態(tài)值娩贷,RACSubject第晰,RACCommand
@interface BlogViewModel : NSObject
/// 數(shù)據(jù)源
@property (nonatomic, strong) NSMutableArray *dataArray;
/// 狀態(tài):刷新狀態(tài)
@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和自定義狀態(tài)
- (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];
}
}];
}