上篇文章我们介绍了Apple版的MVC,今天我们来介绍下一种常用的MVC其实也是基于Apple版MVC的一个变种,首先我们来看下变种的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)
1 2 3 4
| @interface XXApp : NSObject @property (copy, nonatomic) NSString *name; @property (copy, nonatomic) NSString *image; @end
|
接着我们创建我们的View,这次我们的View会持有Model,我们定义一个Delegate用来把点击事件反馈给Controller
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
|
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来响应点击事件
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,我会把笔记都记录下来的
点击查看 2020—课程列表 全网IT各种资源有需求的可以微我,或者你喜欢的课程都可以给我发链接剩下的我来搞定
喜欢的朋友可以扫描关注我的公众号(多多点赞,多多打赏,您的支持是我写作的最大动力)关注有福利可以使用免费梯子自由上网
![iOS_DevTips iOS_DevTips]()