相信大家都听过这种架构,我们来看下图
![]()
跟我们上篇文章说的MVP挺像的,中间的Presenter
,变成了ViewModel
这种架构其实也是三种角色
这种架构,跟MVP
的共同点:
- 都能达到
ViewController
的瘦身,
View
和Model
的隔离,
跟MVP
不同点
就是我们的View
一旦监听到了ViewModel
里的数据变化可以自动更新
,一提到MVVM
我们大家肯定都会想到RAC
这个框架,由于这个框架比较重,为了方便介绍这种架构,我选择另一种方案,KVO
,这里我们要是自己写的话很麻烦,我就直接用Facebook
开源的KVOController
大家可以上GitHub
去下载
下面我们来看下实例
我们还是沿用上篇文章的Demo
来进行修改,首先我们把Presenter
删掉,然后新建我们的ViewModel
,Presenter
里的大部分逻辑还是可以copy
到ViewModel
里的,还有一点就是因为ViewModel
要绑定Model
所以会把Model
的属性都赋值给ViewModel
,然后View
只要监听ViewModel
里的属性变化来改变自己就行了
1 2 3
| @interface XXAppViewModel : NSObject - (instancetype)initWithController:(UIViewController *)controller; @end
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| @interface XXAppViewModel() <XXAppViewDelegate> @property (weak, nonatomic) UIViewController *controller; @property (copy, nonatomic) NSString *name; @property (copy, nonatomic) NSString *image; @end
@implementation XXAppViewModel
- (instancetype)initWithController:(UIViewController *)controller { if (self = [super init]) { self.controller = controller; // 创建View XXAppView *appView = [[XXAppView alloc] init]; appView.frame = CGRectMake(100, 100, 100, 150); appView.delegate = self; appView.viewModel = self; [controller.view addSubview:appView]; // 加载模型数据 XXApp *app = [[XXApp alloc] init]; app.name = @"QQ"; app.image = @"QQ"; // 设置数据完成绑定 self.name = app.name; self.image = app.image; } return self; }
#pragma mark - XXAppViewDelegate - (void)appViewDidClick:(XXAppView *)appView { NSLog(@"viewModel 监听了 appView 的点击"); }
|
接下来我们修改下ViewController
,把Presenter
换成ViewModel
1 2 3 4 5 6 7 8 9 10 11 12 13
| @interface ViewController () @property (strong, nonatomic) XXAppViewModel *viewModel; @end
@implementation ViewController
- (void)viewDidLoad { [super viewDidLoad]; self.viewModel = [[XXAppViewModel alloc] initWithController:self]; }
@end
|
最后我们来看下我们的View
的修改的地方,因为要和ViewModel
进行双向绑定,所以我们要有个ViewModel
对象
1
| @property (weak, nonatomic) XXAppViewModel *viewModel;
|
然后我们在setViewModel
的时候做属性监听这里我们用的KVOController
1 2 3 4 5 6 7 8 9 10 11 12 13
| - (void)setViewModel:(XXAppViewModel *)viewModel { _viewModel = viewModel; __weak typeof(self) weakSelf = self; [self.KVOController observe:viewModel keyPath:@"name" options:NSKeyValueObservingOptionNew block:^(id _Nullable observer, id _Nonnull object, NSDictionary<NSKeyValueChangeKey,id> * _Nonnull change) { weakSelf.nameLabel.text = change[NSKeyValueChangeNewKey]; }]; [self.KVOController observe:viewModel keyPath:@"image" options:NSKeyValueObservingOptionNew block:^(id _Nullable observer, id _Nonnull object, NSDictionary<NSKeyValueChangeKey,id> * _Nonnull change) { weakSelf.iconView.image = [UIImage imageNamed:change[NSKeyValueChangeNewKey]]; }]; }
|
这样我们就完成了双向绑定
,只要我们的ViewModel
里的数据变化了,View
就会监听到改动从而更新自己
总结
Demo只是很简单的一种阐述,很多公司里的都是MVVM+RAC
,有时间我也会开个RAC
的专栏来记录下这个框架的使用,还是那句话,架构这种东西没有唯一,选择适合自己的就行。
明天我们来说说分层架构
点击查看 2020—课程列表 全网IT各种资源有需求的可以微我,或者你喜欢的课程都可以给我发链接剩下的我来搞定
喜欢的朋友可以扫描关注我的公众号(多多点赞,多多打赏,您的支持是我写作的最大动力)关注有福利可以使用免费梯子自由上网
![iOS_DevTips iOS_DevTips]()