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的專欄來記錄下這個框架的使用,還是那句話,架構這種東西沒有唯一,選擇適合自己的就行。

明天我們來說說分層架構


分享到:


相關文章: