iOS架构设计05-MVVM

相信大家都听过这种架构,我们来看下图
MVVM
跟我们上篇文章说的MVP挺像的,中间的Presenter,变成了ViewModel
这种架构其实也是三种角色

  • Model

  • View

  • ViewModel

这种架构,跟MVP的共同点:

  • 都能达到ViewController的瘦身,
  • ViewModel的隔离,

MVP不同点

  • 双向绑定

就是我们的View一旦监听到了ViewModel里的数据变化可以自动更新,一提到MVVM我们大家肯定都会想到RAC这个框架,由于这个框架比较重,为了方便介绍这种架构,我选择另一种方案,KVO,这里我们要是自己写的话很麻烦,我就直接用Facebook开源的KVOController大家可以上GitHub去下载

下面我们来看下实例

我们还是沿用上篇文章的Demo来进行修改,首先我们把Presenter删掉,然后新建我们的ViewModelPresenter里的大部分逻辑还是可以copyViewModel里的,还有一点就是因为ViewModel要绑定Model所以会把Model的属性都赋值给ViewModel,然后View只要监听ViewModel里的属性变化来改变自己就行了

@interface XXAppViewModel : NSObject
- (instancetype)initWithController:(UIViewController *)controller;
@end
@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

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

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.viewModel = [[XXAppViewModel alloc] initWithController:self];
}

@end

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

@property (weak, nonatomic) XXAppViewModel *viewModel;

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

- (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的专栏来记录下这个框架的使用,还是那句话,架构这种东西没有唯一,选择适合自己的就行。

明天我们来说说分层架构

One More Thing

喜欢的朋友可以扫描关注我的公众号(您的支持是我写作的最大动力)

iOS_DevTips

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值