avatar

Catalog
iOS架构设计03-MVC-变种

上篇文章我们介绍了Apple版的MVC,今天我们来介绍下一种常用的MVC其实也是基于Apple版MVC的一个变种,首先我们来看下变种的MVC是什么样子的如下图
MVC-变种

角色还是那三个角色

  • Model

    这个地方不一样了哦,本来是我们的Controller负责和Model进行交互的,变种之后的View是可以拥有这个Model的,相当于View是知道Model的存在的,我们平时开发时可能就会产生这样的一个变种,这样的好处就是Controller的代码不会那么臃肿,我们把Model一些相关的操作封装到View里了

  • View

    反馈一些事件给我们的Controller,上篇没有介绍如何反馈事件,像TableView是通过Delegate反馈给Controller的,我们一般也是用Delegate或者Block来反馈

  • Controller

    还是拥有View,还是创建我们的Model,不同的是不用在Controller里更新View的数据了,这部分逻辑挪到View里了

Demo实例讲解

下面我们来看下Demo,(主要功能就是我们自定义个XXAppView,用来显示上面一张图,下面一行字的控件)

首先我们创建我们的Model,一共两个字段(name,image)

Code
1
2
3
4
@interface XXApp : NSObject
@property (copy, nonatomic) NSString *name;
@property (copy, nonatomic) NSString *image;
@end

接着我们创建我们的View,这次我们的View会持有Model,我们定义一个Delegate用来把点击事件反馈给Controller

Code
1
2
3
4
5
6
7
8
9
10
@class XXApp, XXAppView;

@protocol XXAppViewDelegate <NSObject>
@optional
- (void)appViewDidClick:(XXAppView *)appView;
@end

@interface XXAppView : UIView
@property (strong, nonatomic) XXApp *app;
@end
Code
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
38
39
@interface XXAppView()
@property (weak, nonatomic) UIImageView *iconView;
@property (weak, nonatomic) UILabel *nameLabel;
@end

@implementation XXAppView

- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
UIImageView *iconView = [[UIImageView alloc] init];
iconView.frame = CGRectMake(0, 0, 100, 100);
[self addSubview:iconView];
_iconView = iconView;

UILabel *nameLabel = [[UILabel alloc] init];
nameLabel.frame = CGRectMake(0, 100, 100, 30);
nameLabel.textAlignment = NSTextAlignmentCenter;
[self addSubview:nameLabel];
_nameLabel = nameLabel;
}
return self;
}

- (void)setApp:(XXApp *)app
{
_app = app;

self.iconView.image = [UIImage imageNamed:app.image];
self.nameLabel.text = app.name;
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
if ([self.delegate respondsToSelector:@selector(appViewDidClick:)]) {
[self.delegate appViewDidClick:self];
}
}
@end

最后是我们的Controller,遵循View的Delegate来响应点击事件

Code
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
@interface ViewController () <XXAppViewDelegate>

@end

@implementation ViewController

- (void)viewDidLoad {
[super viewDidLoad];

// 创建view
XXAppView *appView = [[XXAppView alloc] init];
appView.frame = CGRectMake(100, 100, 100, 150);
appView.delegate = self;
[self.view addSubview:appView];

// 加载模型数据,我们以QQ为例
XXApp *app = [[XXApp alloc] init];
app.name = @"QQ";
app.image = @"QQ";

// 设置数据到view上
appView.app = app;
// Apple版的MVC你要这么做
// appView.iconView.image = [UIImage imageNamed:app.image];
// appView.nameLabel.text = app.name;
}

#pragma mark - XXAppViewDelegate
- (void)appViewDidClick:(MJAppView *)appView
{
NSLog(@"控制器监听到了appView的点击");
}

总结

那首先我们看看变种后的MVC的优缺点

  • 优点

对Controller进行瘦身,将View内部的细节封装起来了,外界不知道View内部的具体实现

  • 缺点

View依赖于Model

每一种架构都有他的支持者和反对者,所以说没有哪个架构是最好的,只有哪个架构是最适合的,所以都是MVC大家选自己适合的就行

今天就先介绍到这里,明天我们来看看MVP,还有近期在学习数据结构和算法,小程序,flutter,我会把笔记都记录下来的

点此进入我的简书也会同步更新

One More Thing

点击查看 2020—课程列表 全网IT各种资源有需求的可以微我,或者你喜欢的课程都可以给我发链接剩下的我来搞定

喜欢的朋友可以扫描关注我的公众号(多多点赞,多多打赏,您的支持是我写作的最大动力)关注有福利可以使用免费梯子自由上网

iOS_DevTips

Author: 木子召
Link: https://lizhaobomb.github.io/2020/03/08/iOS%E6%9E%B6%E6%9E%84%E8%AE%BE%E8%AE%A103-MVC-%E5%8F%98%E7%A7%8D/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
Donate
  • 微信
    微信
  • 支付寶
    支付寶

Comment