iOS架构设计之MVC

2019-03-02  本文已影响0人  泪羽12

一、MVC阐述

1.MVC(Model、View、Controller),即模型、视图、控制器;
2.实例描述

就比如画画一样,有模特、画师、画板

3.MVC 的几个明显的特征和体现:
4.简单的 MVC
MVC结构图

二、iOS中的标准MVC

1.比如iOS中的如下例子
#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface TestView : UIView

@property (nonatomic, strong) UILabel *nameLb;

@end

NS_ASSUME_NONNULL_END
#import "TestView.h"

@implementation TestView

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self addSubview:self.nameLb];
    }
    return self;
}

- (UILabel*)nameLb
{
    if (!_nameLb) {
        _nameLb = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 80, 30)];
        _nameLb.center = self.center;
        _nameLb.textAlignment = NSTextAlignmentCenter;
    }
    return _nameLb;
}

/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code
}
*/

@end
#import <Foundation/Foundation.h>

@interface ZYModel : NSObject

@property (nonatomic, copy) NSString *name;

@end
#import "ZYModel.h"

@implementation ZYModel

@end
#import <UIKit/UIKit.h>

@interface ViewController : UIViewController


@end
#import "ViewController.h"
#import "ZYModel.h"
#import "TestView.h"

@interface ViewController ()

@property (nonatomic, strong) ZYModel *zyModel;
@property (nonatomic, strong) TestView *testView;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self loadData];
    [self initTestView];
    
    
}

- (void)loadData
{
    self.zyModel = [[ZYModel alloc] init];
    self.zyModel.name = @"赵扬扬";
}

- (void)initTestView
{
    self.testView = [[TestView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
    self.testView.center =  self.view.center;
    self.testView.nameLb.text = self.zyModel.name;
    [self.view addSubview:self.testView];
}

@end

由上图的例子可以看出,控制器加载模型数据并将数据转换为数据模型。控制器创建视图控件,并将模型数据传递给视图控件

但在实际应用过程中,由于不可避免的交互,数据和界面都会出现更新,因此就会产生通信,在iOS中,MVC模式的通信关系如下图所示


iOSMVC

比如在上面的iOS例子中,如果ZYModel中的name属性改变了,由赵扬扬变成了扬扬,那么TestView上就不能再展示为赵扬扬了,要变成扬扬,这个流程如下:ZYModel通过一种方式告知ViewCotroller我的name改变了,然后由ViewCotroller去告知TestView去更新展示,同样的道理,如果是TestView由于用户的交互要改变ZYModel的name,也是通过ViewCotroller去传达。如下图

iOS标准MVC通信流程

三、MVC变种

在上面的例子中,ZYModel只有一个属性,TestView也只有一个nameLb属性,控制器传值的时候是将ZYModel的对象数据传给TestView的对应属性或控件,但如果ZYModel和TestView都拥有多个属性,那么按照上面所说的模式则只能一一对应传值,而且TestView需要将它需要更新的属性全部暴露出来!

@interface TestView : UIView

@property (nonatomic, strong) UILabel *nameLb;
@property (nonatomic, strong) UILabel *ageLb;
@property (nonatomic, strong) UILabel *sexLb;

@end
@interface ZYModel : NSObject

@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *age;
@property (nonatomic, copy) NSString *sex;

@end

在VIewController中将这些传值

self.testView.nameLb.text = self.zyModel.name;
self.testView.ageLb.text = self.zyModel.age;
self.testView.sexLb.text = self.zyModel.sex;

由上面的例子可以看出,如果属性很多、模型也不知一个,这样一来Controller中的代码会非常臃肿,所以通常我们开发中会做一些改动,让View依赖于Model,将View内部的细节封装起来!如下图所示

iOS中MVC的变种

相对于标准的MVC,变种过的MVC中由于View依赖于Model,所以View的独立性和可复用性不如标准MVC中的View高

但变种MVC的控制器代码更精简一些,View的封装性更好一些。

总结

在实际开发中,如果采用MVC模式,往往会造成控制器比较臃肿,因为往往一个控制器需要承载和管理多个View和Model,再者,这几层之间耦合比较严重,不利于大型项目的维护,其灵活性也比较差。在实际应用中,应尽量给控制器瘦身、抽离业务逻辑。以免代码臃肿、耦合严重!

上一篇 下一篇

猜你喜欢

热点阅读