上篇文章我们介绍了Apple版的MVC
,今天我们来介绍下一种常用的MVC
其实也是基于Apple版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)
@interface XXApp : NSObject
@property (copy, nonatomic) NSString *name;
@property (copy, nonatomic) NSString *image;
@end
接着我们创建我们的View
,这次我们的View
会持有Model
,我们定义一个Delegate
用来把点击事件反馈给Controller
@class XXApp, XXAppView;
@protocol XXAppViewDelegate <NSObject>
@optional
- (void)appViewDidClick:(XXAppView *)appView;
@end
@interface XXAppView : UIView
@property (strong, nonatomic) XXApp *app;
@end
@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
来响应点击事件
@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
喜欢的朋友可以扫描关注我的公众号(您的支持是我写作的最大动力)