iOS架构设计05-MVVM

相信大家都听过这种架构,我们来看下图

iOS架构设计05-MVVM

MVVM

跟我们上篇文章说的MVP挺像的,中间的Presenter,变成了ViewModel
这种架构其实也是三种角色

  • Model
  • View
  • 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里的属性变化来改变自己就行了

<code>@interface XXAppViewModel : NSObject
- (instancetype)initWithController:(UIViewController *)controller;
@end
/<code>
<code>@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 的点击");
}
/<xxappviewdelegate>/<code>

接下来我们修改下ViewController,把Presenter换成ViewModel

<code>@interface ViewController ()
@property (strong, nonatomic) XXAppViewModel *viewModel;
@end

@implementation ViewController

- (void)viewDidLoad {
[super viewDidLoad];

self.viewModel = [[XXAppViewModel alloc] initWithController:self];
}

@end/<code>

最后我们来看下我们的View的修改的地方,因为要和ViewModel进行双向绑定,所以我们要有个ViewModel对象

<code>@property (weak, nonatomic) XXAppViewModel *viewModel;/<code>

然后我们在setViewModel的时候做属性监听这里我们用的KVOController

<code>- (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> * _Nonnull change) {
weakSelf.nameLabel.text = change[NSKeyValueChangeNewKey];
}];

[self.KVOController observe:viewModel keyPath:@"image" options:NSKeyValueObservingOptionNew block:^(id _Nullable observer, id _Nonnull object, NSDictionary<nskeyvaluechangekey> * _Nonnull change) {
weakSelf.iconView.image = [UIImage imageNamed:change[NSKeyValueChangeNewKey]];
}];
}/<nskeyvaluechangekey>/<nskeyvaluechangekey>/<code>

这样我们就完成了双向绑定,只要我们的ViewModel里的数据变化了,View就会监听到改动从而更新自己

总结

Demo只是很简单的一种阐述,很多公司里的都是MVVM+RAC,有时间我也会开个RAC的专栏来记录下这个框架的使用,还是那句话,架构这种东西没有唯一,选择适合自己的就行。

明天我们来说说分层架构


分享到:


相關文章: