当前位置: 首页 > news >正文

【iOS】MVC

文章目录

  • 前言
  • 一、MVC各层职责
    • 1.1、controller层
    • 1.2、model层
    • 1.3、view层
  • 二、总结
  • 三、优缺点
    • 3.1、优点
    • 3.2、缺点
  • 四、代码示例


前言

MVC模式的目的是实现一种动态的程序设计,使后续对程序的修改和扩展简化,并且使程序某一部分的重复利用成为可能。除此之外,此模式通过对复杂度的简化,使程序结构更加直观

一、MVC各层职责

1.1、controller层

  • 生成view,然后组装view
  • 响应View的事件和作为view的代理
  • 处理view的生命周期
  • 处理界面之间的跳转
  • 调用model的数据获取接口,拿到返回数据,处理加工,渲染到view显示

1.2、model层

  • 业务逻辑封装
  • 提供数据接口给controller使用
  • 数据持久化存储和读取
  • 作为数据模型存储数据

1.3、view层

  • 界面元素搭建,动画效果,数据展示
  • 接受用户操作并反馈视觉效果

在这里插入图片描述

二、总结

用户点击 View–> 视图响应事件 -->通过代理传递事件到Controller–>发起网络请求更新Model—>Model处理完数据–>代理或通知给Controller–>改变视图样式–>完成

三、优缺点

3.1、优点

通过Controller来控制全局,同时将view和Model的变化分开,对于复杂混乱的项目结构,有了明确的组织方式。

3.2、缺点

随着业务逻辑增加,大量的逻辑代码放进了Controller,导致Controller越来越臃肿,后期维护成本高。

四、代码示例

我们用一个登录注册小demo来实现我们的MVC框架,首先看一下我们的文件命名:
在这里插入图片描述
可以看到笔者的登录注册都分别实现了MVC,这里给出以登录的MVC进行讲解


Model:

//
//  LandModel.h
//  MVC学习
//
//  Created by 夏楠 on 2023/9/9.
//#import <Foundation/Foundation.h>NS_ASSUME_NONNULL_BEGIN@interface LandModel : NSObject
@property(nonatomic, copy)NSMutableArray *accoutArray;
@property(nonatomic, copy)NSMutableArray *passwordArray;
- (void)InitLandModel;
@endNS_ASSUME_NONNULL_END
//
//  LandModel.m
//  MVC学习
//
//  Created by 夏楠 on 2023/9/9.
//#import "LandModel.h"@implementation LandModel
- (void)InitLandModel {_passwordArray = [[NSMutableArray alloc] init];_accoutArray = [[NSMutableArray alloc] init];
}
@end

View:

//
//  LandView.h
//  MVC学习
//
//  Created by 夏楠 on 2023/9/9.
//#import <UIKit/UIKit.h>NS_ASSUME_NONNULL_BEGIN@interface LandView : UIView
@property(retain, nonatomic)UITextField *textField1;
@property(retain, nonatomic)UITextField *textField2;
@property (nonatomic, strong) UIButton *loginBtn;
@property (nonatomic, strong) UIButton *registeBtn;
- (void)InitView;
@endNS_ASSUME_NONNULL_END
//
//  LandView.m
//  MVC学习
//
//  Created by 夏楠 on 2023/9/9.
//#import "LandView.h"@implementation LandView- (void)InitView {//账号self.textField1 = [[UITextField alloc]init];self.textField1.frame = CGRectMake(60, 350, 280, 40);self.textField1.placeholder = @"请输入账号";self.textField1.borderStyle = UITextBorderStyleRoundedRect;// 设置文本框的圆角self.textField1.layer.cornerRadius = self.textField1.bounds.size.height / 2.0;self.textField1.layer.masksToBounds = YES;self.textField1.backgroundColor = [UIColor whiteColor];  // 设置背景颜色self.textField1.layer.borderColor = [UIColor blackColor].CGColor;  // 设置边框颜色self.textField1.layer.borderWidth = 1.0;  // 设置边框宽度[self.textField1 becomeFirstResponder];[self addSubview:self.textField1];//self.textField1.delegate = self;
//    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
//    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];//用在Controller层//密码self.textField2 = [[UITextField alloc]init];self.textField2.frame = CGRectMake(60, 400, 280, 40);self.textField2.placeholder = @"请输入密码";self.textField2.borderStyle = UITextBorderStyleRoundedRect;// 设置文本框的圆角self.textField2.layer.cornerRadius = self.textField2.bounds.size.height / 2.0;self.textField2.layer.masksToBounds = YES;self.textField2.backgroundColor = [UIColor whiteColor];  // 设置背景颜色self.textField2.layer.borderColor = [UIColor blackColor].CGColor;  // 设置边框颜色self.textField2.layer.borderWidth = 1.0;  // 设置边框宽度self.textField2.secureTextEntry = YES;[self.textField2 becomeFirstResponder];[self addSubview:self.textField2];//    self.textField2.delegate = self;
//    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
//    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];//用在Controller层_loginBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect];_loginBtn.frame = CGRectMake(80, 480, 80, 40);_loginBtn.layer.cornerRadius = _loginBtn.frame.size.height / 6.0;_loginBtn.layer.masksToBounds = YES;_loginBtn.layer.borderWidth = 2.0;_loginBtn.layer.borderColor = [UIColor whiteColor].CGColor;[_loginBtn setTitle:@"登陆" forState:UIControlStateNormal];_loginBtn.tintColor = [UIColor blackColor];_loginBtn.titleLabel.font = [UIFont systemFontOfSize:20];_loginBtn.layer.borderColor = [UIColor blackColor].CGColor;  // 设置边框颜色[self addSubview:self.loginBtn];//    [_loginBtn addTarget:self action:@selector(login) forControlEvents:UIControlEventTouchUpInside];//用在controller层_registeBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect];_registeBtn.frame = CGRectMake(233, 480, 80, 40);_registeBtn.layer.cornerRadius = _registeBtn.frame.size.height / 6.0;_registeBtn.layer.masksToBounds = YES;_registeBtn.layer.borderWidth = 2.0;_registeBtn.layer.borderColor = [UIColor whiteColor].CGColor;[_registeBtn setTitle:@"注册" forState:UIControlStateNormal];_registeBtn.tintColor = [UIColor blackColor];_registeBtn.titleLabel.font = [UIFont systemFontOfSize:20];_registeBtn.layer.borderColor = [UIColor blackColor].CGColor;  // 设置边框颜色[self addSubview:self.registeBtn];//添加注册时间//    [_registeBtn addTarget:self action:@selector(registe) forControlEvents:UIControlEventTouchUpInside];}

Controller:

//
//  ViewController.h
//  MVC学习
//
//  Created by 夏楠 on 2023/9/9.
//#import <UIKit/UIKit.h>
#import "RegistViewController.h"
#import "LandModel.h"
#import "LandView.h"@interface ViewController : UIViewController<UITextFieldDelegate, ConfirmDelegate>
@property (nonatomic, strong)LandView *landView;
@property (nonatomic, strong)LandModel *landModel;
@property (retain, nonatomic)UIAlertController *alert;
@property (nonatomic, strong)RegistViewController *rVC;@end
//
//  ViewController.m
//  MVC学习
//
//  Created by 夏楠 on 2023/9/9.
//#import "ViewController.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];_landModel = [[LandModel alloc] init];[_landModel InitLandModel];_landView = [[LandView alloc] initWithFrame:self.view.frame];[_landView InitView];[self.view addSubview:_landView];[_landView.loginBtn addTarget:self action:@selector(login) forControlEvents:UIControlEventTouchUpInside];[_landView.registeBtn addTarget:self action:@selector(registe) forControlEvents:UIControlEventTouchUpInside];
}登陆函数
- (void)login {int boo1 = 0;for (int i = 0; i < _landModel.accoutArray.count; i ++) {if ([_landModel.accoutArray[i] isEqualToString:_landView.textField1.text] && [_landModel.passwordArray[i] isEqualToString:_landView.textField2.text]) {boo1 = 1;break;}}if (boo1 == 1) {self.alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"登陆成功" preferredStyle:UIAlertControllerStyleAlert];UIAlertAction *confirmAction = [UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {}];[self.alert addAction:confirmAction];[self presentViewController:self.alert animated:YES completion:nil];} else {self.alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"用户名或密码错误" preferredStyle:UIAlertControllerStyleAlert];UIAlertAction *confirmAction = [UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {}];[self.alert addAction:confirmAction];[self presentViewController:self.alert animated:YES completion:nil];}}- (void)registe {if (!_rVC)_rVC = [[RegistViewController alloc] init];_rVC.delegate = self;NSLog(@"%@, %@", _landModel.accoutArray, _landModel.passwordArray);[self presentViewController:_rVC animated:YES completion:nil];
}- (void)confirm:(NSMutableArray *)account password:(NSMutableArray *)password {_landModel.accoutArray = [NSMutableArray arrayWithArray:account];_landModel.passwordArray = [NSMutableArray arrayWithArray:password];
}@end

运行动画:
在这里插入图片描述


相关文章:

【iOS】MVC

文章目录 前言一、MVC各层职责1.1、controller层1.2、model层1.3、view层 二、总结三、优缺点3.1、优点3.2、缺点 四、代码示例 前言 MVC模式的目的是实现一种动态的程序设计&#xff0c;使后续对程序的修改和扩展简化&#xff0c;并且使程序某一部分的重复利用成为可能。除此…...

JavaScript-----jQuery

目录 前言&#xff1a; 1. jQuery介绍 2. 工厂函数 - $() jQuery通过选择器获取元素&#xff0c;$("选择器") 过滤选择器&#xff0c;需要结合其他选择器使用。 3.操作元素内容 4. 操作标签属性 5. 操作标签样式 6. 元素的创建,添加,删除 7.数据与对象遍历…...

Stream流

Stream操作流 在Java 8中&#xff0c;得益于Lambda所带来的函数式编程&#xff0c;引入了一个全新的Stream概念&#xff0c;用于解决已有集合类库既有的弊端。 1.1 集合的迭代 几乎所有的集合&#xff08;如 Collection 接口或 Map 接口等&#xff09;都支持直接或间接的迭代…...

javaee spring 声明式事务管理方式2 注解方式

spring配置文件 <?xml version"1.0" encoding"UTF-8"?> <beans xmlns"http://www.springframework.org/schema/beans"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xmlns:context"http://www.springframewo…...

基于SpringBoot+微信小程序的智慧医疗线上预约问诊小程序

✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取项目下载方式&#x1f345; 一、项目背景介绍&#xff1a; 近年来&#xff0c;随…...

注意力机制讲解与代码解析

一、SEBlock(通道注意力机制) 先在H*W维度进行压缩&#xff0c;全局平均池化将每个通道平均为一个值。 &#xff08;B, C, H, W&#xff09;---- (B, C, 1, 1) 利用各channel维度的相关性计算权重 (B, C, 1, 1) --- (B, C//K, 1, 1) --- (B, C, 1, 1) --- sigmoid 与原特征相…...

微调 TrOCR – 训练 TrOCR 识别弯曲文本

TrOCR(基于 Transformer 的光学字符识别)模型是性能最佳的 OCR 模型之一。在我们之前的文章中,我们分析了它们在单行打印和手写文本上的表现。然而,与任何其他深度学习模型一样,它们也有其局限性。TrOCR 在处理开箱即用的弯曲文本时表现不佳。本文将通过在弯曲文本数据集上…...

Jetsonnano B01 笔记7:Mediapipe与人脸手势识别

今日继续我的Jetsonnano学习之路&#xff0c;今日学习安装使用的是&#xff1a;MediaPipe 一款开源的多媒体机器学习模型应用框架。可在移动设备、工作站和服务 器上跨平台运行&#xff0c;并支持移动 GPU 加速。 介绍与程序搬运官方&#xff0c;只是自己的学习记录笔记&am…...

vue学习之v-if/v-else/v-else-if

v-else/v-else-if 创建 demo7.html,内容如下 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Docum…...

ansible的安装和简单的块使用

目录 一、概述 二、安装 1、选择源 2、安装ansible 3、模块查看 三、实验 1、拓扑​编辑 2、设置组、ping模块 3、hostname模块 4、file模块 ​编辑 5、stat模块 6、copy模块&#xff08;本地拷贝到远程&#xff09; 7、fetch模块与copy模块类似&#xff0c;但作用…...

Android 状态栏显示运营商名称

Android 原生设计中在锁屏界面会显示运营商名称&#xff0c;用户界面中&#xff0c;大概是基于 icon 数量长度显示考虑&#xff0c;对运营商名称不作显示。但是国内基本都加上运营商名称。对图标显示长度优化基本都是&#xff1a;缩小运营商字体、限制字数长度、信号图标压缩上…...

10.Xaml ListBox控件

1.运行界面 2.运行源码 a.Xaml 源码 <Grid Name="Grid1"><!--IsSelected="True" 表示选中--><ListBox x:Name="listBo...

基于vue3和element-plus的省市区级联组件

git地址&#xff1a;https://github.com/ht-sauce/elui-china-area-dht 使用:npm i elui-china-area-dht 默认使用 使用方法 <template><div class"app"><!--默认使用--><elui-china-area-dht change"onChange"></elui-china…...

Paper: 利用RNN来提取恶意软件家族的API调用模式

论文 摘要 恶意软件家族分类是预测恶意软件特征的好方法&#xff0c;因为属于同一家族的恶意软件往往有相似的行为特征恶意软件检测或分类方法分静态分析和动态分析两种&#xff1a; 静态分析基于恶意软件中包含的特定签名进行分析&#xff0c;优点是分析的范围覆盖了整个代码…...

sdkman 安装以及 graalvm安装

sdkman安装以及graalvm安装全过程, (可能需要梯子) tiamTiam-Lenovo:~$ curl -s "https://get.sdkman.io" | bash-syyyyyyys:/yho: -yd./yh/ m..oho. hy ..sh/ :N -/…...

如何正确使用 WEB 接口的 HTTP 状态码和业务状态码?

当设计和开发 Web 接口时&#xff0c;必然会和 HTTP 状态码与业务状态码这两个概念打交道。很多同学可能没有注意过这两个概念或者两者的区别&#xff0c;做得稀里糊涂&#xff0c;接下来详细讲解下二者的定义、区别和使用方法。 HTTP 状态码 HTTP 状态码是由 HTTP 协议定义的…...

Spark【Spark SQL(三)DataSet】

DataSet DataFrame 的出现&#xff0c;让 Spark 可以更好地处理结构化数据的计算&#xff0c;但存在一个问题&#xff1a;编译时的类型安全问题&#xff0c;为了解决它&#xff0c;Spark 引入了 DataSet API&#xff08;DataFrame API 的扩展&#xff09;。DataSet 是分布式的数…...

制作立体图像实用软件:3DMasterKit 10.7 Crack

3DMasterKit 软件专为创建具有逼真 3D 和运动效果的光栅图片而设计&#xff1a;翻转、动画、变形和缩放。 打印机、广告工作室、摄影工作室和摄影师将发现 3DMasterKit 是一种有用且经济高效的解决方案&#xff0c;可将其业务扩展到新的维度&#xff0c;提高生成的 3D 图像和光…...

高校 Web 站点网络安全面临的主要的威胁

校园网 Web 站点的主要安全威胁来源于计算机病毒、内部用户恶意攻击和 破坏、内部用户非恶意的错误操作和网络黑客入侵等。 2.1 计算机病毒 计算机病毒是指编制者在计算机程序中插入的破坏计算机功能或者数据&#xff0c; 影响计算机使用并且能够自我复制的一组计算机指令或…...

vue前端解决跨域

1,首先 axios请求&#xff0c;看后端接口路径&#xff0c;http://122.226.146.110:25002/api/xx/ResxxList&#xff0c;所以baseURL地址改成 ‘/api’ let setAxios originAxios.create({baseURL: /api, //这里要改掉timeout: 20000 // request timeout}); export default s…...

地震勘探——干扰波识别、井中地震时距曲线特点

目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波&#xff1a;可以用来解决所提出的地质任务的波&#xff1b;干扰波&#xff1a;所有妨碍辨认、追踪有效波的其他波。 地震勘探中&#xff0c;有效波和干扰波是相对的。例如&#xff0c;在反射波…...

MongoDB学习和应用(高效的非关系型数据库)

一丶 MongoDB简介 对于社交类软件的功能&#xff0c;我们需要对它的功能特点进行分析&#xff1a; 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具&#xff1a; mysql&#xff1a;关系型数据库&am…...

线程同步:确保多线程程序的安全与高效!

全文目录&#xff1a; 开篇语前序前言第一部分&#xff1a;线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分&#xff1a;synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分&#xff…...

苍穹外卖--缓存菜品

1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得&#xff0c;如果用户端访问量比较大&#xff0c;数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据&#xff0c;减少数据库查询操作。 缓存逻辑分析&#xff1a; ①每个分类下的菜品保持一份缓存数据…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明

AI 领域的快速发展正在催生一个新时代&#xff0c;智能代理&#xff08;agents&#xff09;不再是孤立的个体&#xff0c;而是能够像一个数字团队一样协作。然而&#xff0c;当前 AI 生态系统的碎片化阻碍了这一愿景的实现&#xff0c;导致了“AI 巴别塔问题”——不同代理之间…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)

文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

uniapp 开发ios, xcode 提交app store connect 和 testflight内测

uniapp 中配置 配置manifest 文档&#xff1a;manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号&#xff1a;4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...

PostgreSQL——环境搭建

一、Linux # 安装 PostgreSQL 15 仓库 sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpm# 安装之前先确认是否已经存在PostgreSQL rpm -qa | grep postgres# 如果存在&#xff0…...

WebRTC从入门到实践 - 零基础教程

WebRTC从入门到实践 - 零基础教程 目录 WebRTC简介 基础概念 工作原理 开发环境搭建 基础实践 三个实战案例 常见问题解答 1. WebRTC简介 1.1 什么是WebRTC&#xff1f; WebRTC&#xff08;Web Real-Time Communication&#xff09;是一个支持网页浏览器进行实时语音…...

Modbus RTU与Modbus TCP详解指南

目录 1. Modbus协议基础 1.1 什么是Modbus? 1.2 Modbus协议历史 1.3 Modbus协议族 1.4 Modbus通信模型 🎭 主从架构 🔄 请求响应模式 2. Modbus RTU详解 2.1 RTU是什么? 2.2 RTU物理层 🔌 连接方式 ⚡ 通信参数 2.3 RTU数据帧格式 📦 帧结构详解 🔍…...