欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

iOS - MVC学习

程序员文章站 2022-06-25 09:17:26
目录MVC简介MVC的优缺点优点缺点MVC之间的通信Model和View如何向Controller发送消息?实例代码(登陆注册demo)参考博客MVC简介MVC开始是存在于桌面程序中的,M是指业务模型,V是指用户界面,C则是控制器,使用MVC的目的是将M和V的实现代码分离,从而使同一个程序可以使用不同的表现形式。比如一批统计数据可以分别用柱状图、饼图来表示。C存在的目的则是确保M和V的同步,一旦M改变,V应该同步更新。Model(模型):表示应用程序核心(比如数据库记录列表),是应用程序中用于处理应...

MVC简介

MVC开始是存在于桌面程序中的,M是指业务模型,V是指用户界面,C则是控制器,使用MVC的目的是将M和V的实现代码分离,从而使同一个程序可以使用不同的表现形式。比如一批统计数据可以分别用柱状图、饼图来表示。C存在的目的则是确保M和V的同步,一旦M改变,V应该同步更新。

  • Model(模型):表示应用程序核心(比如数据库记录列表),是应用程序中用于处理应用程序数据逻辑的部分,通常模型对象负责在数据库中存取数据。
  • View(视图):显示数据(数据库记录),通常视图是依据模型数据创建的。
  • Controller(控制器):处理输入(写入数据库记录),是应用程序中处理用户交互的部分。通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据。

iOS - MVC学习

MVC的优缺点

优点

  • 耦合性低
    视图层和业务层分离,这样就允许更改视图层代码而不用重新编译模型和控制器代码,因为模型与控制器和视图相分离,所以很容易改变应用程序的数据层。由于运用MVC的应用程序的三个部件是相互独立,改变其中一个不会影响其它两个,所以依据这种设计思想能构造良好的松耦合的构件。
  • 重用性高
    随着技术的不断进步,需要用越来越多的方式来访问应用程序。MVC模式允许使用各种不同样式的视图来访问同一个服务器端的代码,因为多个视图能共享一个模型。
  • 可维护性高

缺点

  • 没有明确的定义
    完全理解MVC并不是很容易。使用MVC需要精心的计划,由于它的内部原理比较复杂,所以需要花费一些时间去思考。同时由于模型和视图要严格的分离,这样也给调试应用程序带来了一定的困难。每个构件在使用之前都需要经过彻底的测试。
  • 不适合小型,中等规模的应用程序
  • 增加系统结构和实现的复杂性
    对于简单的界面,严格遵循MVC,使模型、视图与控制器分离,会增加结构的复杂性,并可能产生过多的更新操作,降低运行效率。

MVC之间的通信

iOS - MVC学习

  • 白色虚线:可直接引用到 Controller 中实例化;
  • 白色实线:不可直接引用到 Controller 中实例化,需要用其他同步手段进行数据和状态的同步;
  • 黄色实线:不可直接通信;
  • Controller->Model/View
    直接在Controller中引入并实例化Model和View

Model和View如何向Controller发送消息?

Model->Controller

  • KVO(监听)
    Controller通过监听,监听Model的每个属性的变化来做出响应事件

  • Notification(通知)
    Model中创建一个NSNotificationCenter,在Controller中,创建一个方法来接收通知。当Model发生变化时, 他会发送一个通知,而Controller会接收通知

View->Controller

  • target-Action
    Controller给View添加一个target,当用户的触摸事件发生时,view产生action,Controller接收到之后做出相应的响应。

  • delegate 或 datasource
    Controller可以作为view的代理,当View中检测到被触摸,他会通知Controller做出响应

实例代码(登陆注册demo)

  • 创建三个文件夹,分别命名为M V C
  • 新建LoginModel类,继承于NSObject
  • 新建LoginView,继承于UIView
  • 新建LoginViewController,继承于UIViewController
    iOS - MVC学习
    在LoginView中写出需要实现的两个button和两个textField
//LoginView.h中
@interface LoginView : UIView

@property (nonatomic, strong) UITextField *loginTextFiled;
@property (nonatomic, strong) UITextField *passTextFiled;
@property (nonatomic, strong) UIButton *loginButton;
@property (nonatomic, strong) UIButton *registerButton;

- (void) viewInit;//初始化View,在controller中调用

@end
//LoginView.m中
#import "LoginView.h"

@implementation LoginView

- (void) viewInit {
    self.backgroundColor = [UIColor whiteColor];
    
    _loginTextFiled = [[UITextField alloc] initWithFrame:CGRectMake(70, 260, 260, 50)];
    [self addSubview:_loginTextFiled];
    [_loginTextFiled setBorderStyle:UITextBorderStyleRoundedRect];
    _loginTextFiled.layer.borderWidth = 3;
    _loginTextFiled.layer.cornerRadius = 4;
    _loginTextFiled.tintColor = [UIColor blackColor];
    _loginTextFiled.placeholder = @"Name...";
    
    _passTextFiled = [[UITextField alloc] initWithFrame:CGRectMake(70, 340, 260, 50)];
    [self addSubview:_passTextFiled];
    [_passTextFiled setBorderStyle:UITextBorderStyleRoundedRect];
    _passTextFiled.layer.borderWidth = 3;
    _passTextFiled.layer.cornerRadius = 4;
    _passTextFiled.tintColor = [UIColor blackColor];
    _passTextFiled.placeholder = @"Password...";
    _passTextFiled.secureTextEntry = YES;
    
    _loginButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    [self addSubview:_loginButton];
    [_loginButton.layer setMasksToBounds:YES];
    _loginButton.layer.borderWidth = 2;
    _loginButton.layer.cornerRadius = 4;
    _loginButton.frame = CGRectMake(60, 500, 120, 40);
    [_loginButton setTitle:@"Login" forState:UIControlStateNormal];
    [_loginButton setTintColor:[UIColor blackColor]];
    
    _registerButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    [self addSubview:_registerButton];
    _registerButton.frame = CGRectMake(220, 500, 120, 40);
    _registerButton.layer.borderWidth = 2;
    _registerButton.layer.cornerRadius = 4;
    [_registerButton setTitle:@"Regist" forState:UIControlStateNormal];
    [_registerButton setTintColor:[UIColor blackColor]];
}

因为MVC方法中,View中不实现数据的处理,所以将target-action方法放在Controller中实现

在Model中放入数据(登陆时的账号和密码)

//LoginModel.h中
@interface LoginModel : NSObject

@property (nonatomic, strong) NSMutableArray *nameArr;
@property (nonatomic, strong) NSMutableArray *passArr;

- (void) modelInit;

@end
//LoginModel.m中
#import "LoginModel.h"

@implementation LoginModel

- (void) modelInit {
    
    _nameArr = [[NSMutableArray alloc] init];
    [_nameArr addObject:@"123"];
    
    _passArr = [[NSMutableArray alloc] init];
    [_passArr addObject:@"123"];
    
}

最后在Controller中实例化LoginModel和LoginView对其中的方法进行调用

//LoginViewController.h中
#import <UIKit/UIKit.h>
#import "LoginView.h"
#import "LoginModel.h"

NS_ASSUME_NONNULL_BEGIN

@interface LoginViewController : UIViewController

@property (nonatomic, strong) LoginView *loginView;
@property (nonatomic, strong) LoginModel *loginModel;

@end
// LoginViewController.m中
#import "LoginViewController.h"
#import "RegisterViewController.h"

@interface LoginViewController () <RegisterDelegate>

@end

@implementation LoginViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    //self.view.backgroundColor
    _loginView = [[LoginView alloc] initWithFrame:self.view.frame];
    [self.view addSubview:_loginView];
    [_loginView viewInit];
    [_loginView.loginButton addTarget:self action:@selector(pressLogin) forControlEvents:UIControlEventTouchUpInside];
    [_loginView.registerButton addTarget:self action:@selector(pressRegister) forControlEvents:UIControlEventTouchUpInside];
    
    _loginModel = [[LoginModel alloc] init];
    [_loginModel modelInit];
    
    
    // Do any additional setup after loading the view.
}
- (void) pressLogin {
    for (int i = 0; i < _loginModel.nameArr.count; i++) {
        if ([_loginView.loginTextFiled.text isEqualToString:_loginModel.nameArr[i]] && [_loginView.passTextFiled.text isEqualToString:_loginModel.passArr[i]]) {
            [self showError:@"您已成功登陆"];
        }
        else{
            [self showError:@"用户名或密码错误!"];
        }
    }
}

- (void) pressRegister {
    RegisterViewController *registerVC = [[RegisterViewController alloc] init];
    registerVC.modalPresentationStyle = UIModalPresentationFullScreen;
    registerVC.registerDelegate = self;
    [self presentViewController:registerVC animated:YES completion:nil];
}

//协议传值
- (void) passData: (NSString *) name AndPassword: (NSString *) pass {
    _loginView.loginTextFiled.text = name;
    _loginView.passTextFiled.text = pass;
    [_loginModel.nameArr addObject:name];
    [_loginModel.passArr addObject:pass];
}

//弹出对话框
- (void) showError: (NSString *) message {
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"bling~" message:message preferredStyle:UIAlertControllerStyleAlert];
    [alert addAction:[UIAlertAction actionWithTitle:@"bingo" style:UIAlertActionStyleDefault handler:nil]];
    
    [self presentViewController:alert animated:YES completion:nil];
}

注册界面与登陆界面类似,多了协议传值

//RegisterViewController.m
#import "RegisterViewController.h"

@interface RegisterViewController ()

@end

@implementation RegisterViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    _registerView = [[RegiserView alloc] initWithFrame:self.view.frame];
    [self.view addSubview:_registerView];
    [_registerView RviewInit];
    
    [_registerView.cancelButton addTarget:self action:@selector(pressCancel) forControlEvents:UIControlEventTouchUpInside];
    [_registerView.registerButton addTarget:self action:@selector(pressRegist) forControlEvents:UIControlEventTouchUpInside];
    
    _registerModel = [[RegisterModel alloc] init];
    
}

- (void) pressRegist {
    _registerModel.nameStr = _registerView.loginTextFiled.text;
    _registerModel.passStr = _registerView.passTextFiled.text;
 
 	//传值
    if ([_registerDelegate respondsToSelector:@selector(passData:AndPassword:)]) {
        [_registerDelegate passData:_registerModel.nameStr AndPassword:_registerModel.passStr];
    }
    
    [self dismissViewControllerAnimated:YES completion:nil];
}


- (void) pressCancel {
    [self dismissViewControllerAnimated:YES completion:nil];
}

参考博客

本文地址:https://blog.csdn.net/weixin_45747214/article/details/108689298

相关标签: ios