IOS项目架构
一、架构分层:
三层架构:
- 应用层/界面层
- 业务层
- 数据层
四层架构:
- 应用层/界面层
- 业务层
- 网络层
- 本地数据层
理解:
应用层用来管理加载界面比如tableview。
业务层用来处理项目业务,比如处理登陆,加载列表数据等创建的manager/serveice类就属于业务层。
数据层,可分为网络层和本地数据层,分别用来发起网络请求,从本地存取数据库,提供数据给业务层。
例如一个新闻APP:
image.png
二、MVC/MVP/MVVM:
这三种架构都属于应用层层面的架构
1.MVC(苹果版) :
model —view —controller
image.png image.png
理解:UITableView就是典型的苹果版MVC架构:controller加载tableview,获取model数据,在controller中将model的内容填充给view,比如cell.nametext = model.name;
cell和model不相互依赖。
优点:model,view可以重复利用,可以单独使用(UITableView就是典型的苹果版MVC)
缺点:controller代码过于臃肿
2.MVC(变种版) :
model —view —controller
image.png
理解:也是我们常用的view绑定一个model,cell.userinfo = userInfoModel, 这样就把view属性的赋值操作放在view内部,可以隐藏view的一些属性。
优点:对controller瘦身,将view的内部细节封装,外界不知道view内部具体实现
缺点:view依赖于model
3.MVP:
model —view —presenter
image.png
理解:presenter内部完成view的model的绑定,view和model不相互依赖。controller只需创建管理presenter即可,从而使controller更加精简。
4.MVVM
model — view — view-model
image.png image.png
MVVM框架是在MVC的基础上演化而来,MVVM想要解决的问题是尽可能地减少Controller的任务。
- Model:程序中要操纵的实际对象的抽象
- View(ViewController):MVVM中的View不再是UIView的子类,而变成了UIViewController的子类。这里的View实际上就是MVC中剥离了处理呈现View逻辑部分的Controller,因此它仍然有各种UIView的属性,仍然有ViewController的声明周期的各种方法,但是这里的Controller不再负责数据的请求以及处理逻辑,因此不再臃肿。
- ViewModel:MVVM中,ViewModel代替了MVC中的Controller成为了协调者的角色,ViewModel被View(ViewController)持有,同时持有Model。数据请求以及处理逻辑都放在ViewModel中,View(ViewController)就瘦了下来。
理解:viewmodel类似于presenter,controller只需创建管理viewmodel即可,从而使controller更加精简。
核心区别是view持有viewmodel,。
从而view可以监听viewmodel属性的变化,从而更新view。
所以一般MVVM+RAC/KVO搭配使用
viewcontroller.m
//创建并管理viewmodel
- (void)viewDidLoad {
[super viewDidLoad];
self.viewModel = [[AppViewModel alloc] initWithController:self];
}
ViewModel.m
//viewmodel创建并管理view和model,处理view的点击事件
- (instancetype)initWithController:(UIViewController *)controller
{
if (self = [super init]) {
self.controller = controller;
// 创建View
AppView *appView = [[AppView alloc] init];
appView.frame = CGRectMake(100, 100, 100, 150);
appView.delegate = self;
//view持有viewmodel
appView.viewModel = self;
[controller.view addSubview:appView];
// 加载模型数据
App *app = [[App alloc] init];
app.name = @"QQ";
app.image = @"QQ";
// 设置数据
self.name = app.name;
self.image = app.image;
}
return self;
}
#pragma mark - AppViewDelegate
- (void)appViewDidClick:(AppView *)appView
{
NSLog(@"viewModel 监听了 appView 的点击");
}
view.m
//view拥有viewmodel,并监听viewmodel的属性变化
- (void)setViewModel:(AppViewModel *)viewModel
{
_viewModel = viewModel;
__weak typeof(self) waekSelf = self;
[self.KVOController observe:viewModel keyPath:@"name" options:NSKeyValueObservingOptionNew block:^(id _Nullable observer, id _Nonnull object, NSDictionary<NSKeyValueChangeKey,id> * _Nonnull change) {
waekSelf.nameLabel.text = change[NSKeyValueChangeNewKey];
}];
[self.KVOController observe:viewModel keyPath:@"image" options:NSKeyValueObservingOptionNew block:^(id _Nullable observer, id _Nonnull object, NSDictionary<NSKeyValueChangeKey,id> * _Nonnull change) {
waekSelf.iconView.image = [UIImage imageNamed:change[NSKeyValueChangeNewKey]];
}];
}