关于 MVVM 和 MVC 的详解 以及优缺点可以移步到参考链接,这里不再做多解释了。写这篇文章主要是想表达MVVM一个简单的实现(有很多大神也发了很多demo 过于复杂)。
MVVM 实践
MVVM_demo.png
上面是这个 demo 的文件结构
View文件:自定义的view
Model文件: 数据
ViewModel文件:业务逻辑,网络请求,数据缓存,
ViewController文件:负责事件绑定 以及UI的展示
MVVM.png
在ViewController 实现事件绑定。把数据处理组件化 解耦,
//绑定ViewModel
- (void)bindModel {
__weak typeof(self) weekSelf = self;
//解耦
self.dataSource = [[JNTableDataSource alloc] initWithCellIdentifier:@"cellid" configure:^(JNTableViewCell* cell, JNModel *model, NSIndexPath * _Nonnull indexPath) {
cell.textLabel.text = model.name;
cell.detailTextLabel.text = model.idNumber;
}];
//绑定 ViewModel
self.viewModel = [[JNViewModel alloc] initWithSucc:^(id _Nonnull datas) {
weekSelf.refreshBtn.hidden = YES;
weekSelf.dataSource.datas = datas;
[self.tableView reloadData];
} fail:^{
}];
}
#pragma mark --UITableViewDelegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
JNModel *model = self.viewModel.datas[indexPath.row];
//点击事件 绑定
self.viewModel.selectName = model.name;
}
解重:
ViewModel.m 把 业务逻辑,网络请求,数据缓存 从 MVC 中的 Controller 拆分出来,
//设置初始状态
- (instancetype)initWithSucc:(succ)succ fail:(fail)fail {
self = [super init];
if (self) {
_succ = succ;
_fail = fail;
_datas = [NSMutableArray new];
//观察者模式 实现 反向绑定
[self addObserver:self forKeyPath:@"selectName" options:NSKeyValueObservingOptionNew context:nil];
}
return self;
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
NSString *selectName = change[NSKeyValueChangeNewKey];
@synchronized (self) {
NSInteger index = [self.datas indexOfObjectPassingTest:^BOOL(JNModel *obj, NSUInteger idx, BOOL * _Nonnull stop) {
return [obj.name isEqualToString:selectName];
}];
[self.datas removeObjectAtIndex:index];
}
if (self.succ) {
self.succ(self.datas);
}
}
- (void)dealloc {
[self removeObserver:self forKeyPath:@"selectName" context:nil];
}
- (void)refreshAction {
//模拟请求
[[NSOperationQueue new] addOperationWithBlock:^{
@synchronized (self) {
[self.datas removeAllObjects];
for (int i = 0; i<30; i++) {
JNModel *model = [[JNModel alloc] init];
model.name = [NSString stringWithFormat:@"test%d",i];
model.idNumber = [NSString stringWithFormat:@"atTest%d",i];
[self.datas addObject:model];
}
}
sleep(2.0);
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
if (self.succ) {
self.succ(self.datas);
}
}];
}];
}
demo链接
https://github.com/Jniying/single_MVVM_Demo
参考链接
https://www.jianshu.com/p/caaa173071f3
https://www.jianshu.com/p/f1d0f7f01130
https://casatwy.com/iosying-yong-jia-gou-tan-wang-luo-ceng-she-ji-fang-an.html
(ps:之前的文章存在很多错误的地方,没有时间更新,修复bug时间2019年05月27日。 有更好的建议和意见欢迎留言,共同学习进步)