【iOS】MVC架构模式
文章目录
- 前言
- MVC架构模式
- 基本概念
- 通信方式
- 简单应用
- 总结
前言
“MVC”,即Model(模型),View(视图),Controller(控制器),MVC模式是架构模式的一种。
关于“架构模式”:
架构模式(Architectural Pattern)是软件架构中常见的组织结构解决方案,用于指导大型软件系统的设计。它们描述了软件系统常见的组织结构和它们之间的相互关系,为构建复杂软件系统提供了经验证的解决方案。架构模式提供了一种通用的、可重用的解决方案来处理在软件设计中遇到的常见问题。
常见的架构模式包括:
1.分层模式(Layered Pattern):
将系统分割成多个层次,每一层提供特定的服务,并且只与相邻层次通信。例如,一个典型的三层架构包括表示层(用户界面)、业务逻辑层和数据访问层。
2.客户端-服务器模式(Client-Server Pattern):
系统分为两部分:服务器提供服务,客户端请求服务。这种模式广泛应用于网络应用程序。
3.模型-视图-控制器模式(Model-View-Controller Pattern, MVC):
用于实现用户界面的分离关注点,将应用程序分为三个核心组件:模型(数据和业务逻辑)、视图(用户界面)和控制器(业务逻辑和用户界面之间的通信)。
4.管道-过滤器模式(Pipeline-Filter Pattern):
在这种模式中,每个处理步骤(过滤器)作为数据流(管道)中的一个阶段,数据流从一个过滤器流向下一个过滤器。
5.事件驱动架构模式(Event-Driven Pattern):
系统作为一系列异步事件和回调处理函数的集合。这种模式适用于需要高响应性和可伸缩性的应用。
6.微内核模式(Microkernel Pattern):
系统的核心功能由一个小型的、可扩展的内核提供,其他功能则作为插件或模块附加在内核周围。
7.代理模式(Proxy Pattern):
为其他对象提供一个代理或占位符,以控制对这个对象的访问。这在远程代理、虚拟代理和保护代理中很常见。
8.发布-订阅模式(Publish-Subscribe Pattern):
一种事件驱动的通信模式,发布者发送事件,而订阅者对这些事件做出响应,但发布者和订阅者之间没有直接的联系。
9.黑板模式(Blackboard Pattern):
多个模块或组件通过一个共享的数据空间(黑板)进行通信和协作,以解决复杂问题。
10.MVC的变体模式:
包括表现层-业务逻辑层-数据访问层(Presentation-Logic-Data Access, PLDA)、模型-视图-视图模型(Model-View-ViewModel, MVVM)和模型-视图-适配器(Model-View-Adapter, MVA)等。
MVC架构模式
基本概念
‘M’——模型(Model):视图类所需要的数据,例如:表格需要显示的文字。
‘V’——视图(View):屏幕上显示的UI,响应用户事件,接受用户输入。例如:按钮,标签,进度条等。
‘C’——控制器(Controller):连接视图类和模型类,任务是使数据显示在屏幕上,主要负责转发请求,对请求进行处理。例如:控制器将表格需要使用的数据“填入”表格视图中,将表格视图显示出来。
关于这三者的关系,我参考了如下图例来理解:
斯坦福大学的iOS公开课第一课:

苹果官方的图解:

在这里可以看出来“V”和“M”是相互独立的,在iOS开发的MVC框架中,我们可以理解为view和model相互独立,两者属于不知道对方的存在的陌生人关系。
⚠️Model 和 View 是相互独立的
这是很容易犯错的一点,因为MVC 架构模式是在软件设计中通用的,不只是iOS 开发。iOS 开发中的MVC模式是基于传统的MVC 架构的,只是在具体实现上有所不同。Apple 官方对于iOS开发中的MVC 模式和传统的MVC 架构有所不同,如果查阅传统的MVC 架构会发现,View 和Model 之间是有通信的。
(转自 SungKaikai 文章链接)
通信方式
- 控制器C可以直接访问模型M:将模型直接作为控制器的属性。
- 控制器C可以直接访问视图V:将视图直接作为控制器的属性。
- 模型M与视图V无法直接访问对方:二者完全解耦,不能引用对方,把对方设置为属性。
- 视图V到控制器C的通信:
目标动作机制(target - action):用户与视图交互触发控制器的方法。例如:点击按钮后实现视界面跳转,网络请求,刷新UI等。
委托机制(delegate):视图向控制器询问某些自己无法决定的事情,或是让控制器帮助自己做一些自己独立无法完成的事情。 因为控制器才是掌握全局的角色,很多时候视图是无法自己做决定的。例如:表格问控制器:我可以滚动么?然后控制器给予回答告知是否可以继续滚动。 如果表格的高度很小,那么就可以不让它滚动。但是如果表格的高度已经超过了屏幕的高度,这时候如果让它自作主张无法滚动就不好了。
数据源机制(dataSource):视图让控制器给它将要显示的数据。例如:音乐的数据存在于模型里,控制器访问模型,从模型里拿到数据后告诉视图如何显示出歌曲。 - 模型M到控制器C的通信
广播机制(Notification):控制器注册监听某模型数据变化的广播频道,当此模型数据变化后向该控制器发送广播,告知模型变化情况。
KVO机制(Key-Value Observing):模型作为控制器的属性,当模型属性被修改后,持有此模型属性的控制器就会收到通知。
——斯坦福大学iOS开发公开课总结(一):iOS的MVC框架
简单应用
先看看创建的文件:

1.创建 Model
模型通常是一个或多个类,它们包含数据和对数据进行操作的方法。例如,一个简单的Person测试模型:
#import <Foundation/Foundation.h>NS_ASSUME_NONNULL_BEGIN@interface TestModel : NSObject@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSNumber *age;- (void)performAction;@endNS_ASSUME_NONNULL_END
#import "TestModel.h"@implementation TestModel- (void)performAction {// 这里可以放置一些业务逻辑,例如打印一条消息NSLog(@"Hello, my name is %@ and I am %@ years old.", self.name, self.age);
}@end
这里的代码存在一些bug,后续笔者修改后会再呈现完整代码。
总结
在模型类里是不能调用控制器的方法的,模型类只能被控制器调用并且当所拥有的数据改变后通知使用自己的控制器数据的改变。更不能直接给视图通知让视图自己更新UI。
参考文章:iOS 架构设计代码实例学习-MVC 模式
你真的了解MVC吗?
相关文章:
【iOS】MVC架构模式
文章目录 前言MVC架构模式基本概念通信方式简单应用 总结 前言 “MVC”,即Model(模型),View(视图),Controller(控制器),MVC模式是架构模式的一种。 关于“架构模式”&a…...
ML 系列:机器学习和深度学习的深层次总结(08)—欠拟合、过拟合,正确拟合
ML 系列赛:第 9 天 — Under、Over 和 Good Fit 文章目录 一、说明二、了解欠拟合、过拟合和实现正确的平衡三、关于泛化四、欠拟合五、过拟合六、适度拟合七、结论 一、说明 在有监督学习过程中,对于指定数据集进行训练,训练结果存在欠拟合…...
Unity-物理系统-刚体加力
一 刚体自带添加力的方法 给刚体加力的目标就是 让其有一个速度 朝向某一个方向移动 1.首先应该获取刚体组件 rigidBody this.GetComponent<Rigidbody>(); 2.添加力 //相对世界坐标 //世界坐标系 Z轴正方向加了一个里 //加力过后 对象是否停止…...
深入探究PR:那些被忽视却超实用的视频剪辑工具
如果想要了解视频剪辑的工具,那一定听说过pr视频剪辑吧。如果你是新手其实我更推荐你从简单的视频剪辑工具入手,这次我就介绍一些简单好操作的视频剪辑工具来入门吧。 1.福晰视频剪辑 连接直达>>https://www.pdf365.cn/foxit-clip/ 这款工具操…...
Unity-麦克风输入相关
private AudioClip clip; 知识点一 获取设备麦克风信息 string[] strs Microphone.devices; for (int i 0; i < strs.Length; i) { print(strs[i]); } 知识点二 开始录制 参数一:设备名 传空使用默认设备 参数二:超过录…...
NLP--自然语言处理学习-day1
一.初步认识NLP 自然语言处理(Natural Language Processing, NLP)是计算机科学和人工智能(AI)的一个交叉领域,旨在使计算机能够理解、分析、生成和处理人类语言的能力。它结合了计算语言学、人工智能、机器学习和语言…...
ER论文阅读-Incomplete Multimodality-Diffused Emotion Recognition
基本介绍:NeurIPS, 2024, CCF-A 原文链接:https://proceedings.neurips.cc/paper_files/paper/2023/file/372cb7805eaccb2b7eed641271a30eec-Paper-Conference.pdf Abstract 人类多模态情感识别(MER)旨在通过多种异质模态&#x…...
Matlab自学笔记36:日期时间型的概念、分类和创建方法
1.概念 日期时间型(Dates and Time)数据具有灵活的显示格式和高达毫微秒的精度,并且可以处理时区、夏令时和平闰年等特殊因素 2.日期时间型数据有以下三种表示方式 (1)Datetime型,表示日期时间点&#x…...
Spring Boot自定义配置项
Spring Boot自定义配置项 配置文件 在application.properties文件添加需要的配置 比如: file.pathD:\\flies\\springboot\\ConfigurationProperties 注解 使用注解ConfigurationProperties将配置项和实体Bean关联起来,实现配置项和实体类字段的关联&…...
【C++篇】C++类与对象深度解析(六):全面剖析拷贝省略、RVO、NRVO优化策略
文章目录 C类与对象前言读者须知RVO 与 NRVO 的启用条件如何确认优化是否启用? 1. 按值传递与拷贝省略1.1 按值传递的概念1.2 示例代码1.3 按值传递的性能影响1.3.1 完全不优化 1.4 不同编译器下的优化表现1.4.1 Visual Studio 2019普通优化1.4.2 Visual Studio 202…...
什么时候用synchronized,什么时候用Reentrantlock
文章目录 使用 synchronized 的场景使用 ReentrantLock 的场景综合考虑 使用 synchronized 的场景 synchronized 是 Java 内置的同步机制,使用起来比较简单且常用于如下场景: 1、简单的同步逻辑:当你的同步逻辑非常简单,比如只需…...
[ffmpeg]音频格式转换
本文主要梳理 ffmpeg 中的音频格式转换。由于采集的音频数据和编码器支持的音频格式可能不一样,所以经常需要进行格式转换。 API 调用 常用 API struct SwrContext *swr_alloc(void); int swr_init(struct SwrContext *s); struct SwrContext *swr_alloc_set_opt…...
SSRF工具类-SsrfTool
为了帮助开发人员和安全研究人员检测和修复SSRF(Server-Side Request Forgery)漏洞,存在 多种工具。这里我将给出一个简单的工具类示例,这个工具类可以用来检查一个给定的URL是否可 能引发SSRF攻击。请注意,这个工具类主要用于教育目的,并不意味着它可以完全防止所有的…...
python集合运算介绍及示例代码
Python 中的集合(set)是一种数据类型,用于存储唯一元素的无序集合。集合支持多种运算,如并集、交集、差集和对称差集,方便执行数学上的集合操作。 1. 创建集合 可以使用大括号 {} 或者 set() 函数创建集合࿱…...
『功能项目』按钮的打开关闭功能【73】
本章项目成果展示 我们打开上一篇72QFrameWork制作背包界面UGUI的项目, 本章要做的事情是制作打开背包与修改器的打开关闭按钮 首先打开UGUICanvas复制button按钮 重命名为ReviseBtn 修改脚本:UIManager.cs 将修改器UI在UGUICanvas预制体中设置为隐藏 运…...
Linux 常用命令 - more 【分页显示文件内容】
简介 more 命令源自英文单词 more, 表示 “更多”,它是一个基于文本的程序,用于查看文本文件的内容。该命令会逐页显示文件内容,允许用户按页浏览大型文本文件。当用户完成当前页的阅读后,可以通过按键(空格键或回车键…...
Kotlin Android 环境搭建
Kotlin Android 环境搭建 1. 引言 Kotlin 已成为 Android 开发的官方语言之一,因其简洁、表达性强和易于维护的特点而受到广大开发者的喜爱。在本教程中,我们将详细介绍如何在您的计算机上搭建 Kotlin Android 开发环境。 2. 系统要求 在开始搭建 Kotlin Android 开发环境…...
常见协议及其默认使用的端口号
在网络通信中,端口号用于标识特定的应用程序或服务。IANA(Internet Assigned Numbers Authority)负责分配和管理这些端口号。端口号分为三个范围: 熟知端口(Well-Known Ports):0到1023…...
04-Docker常用命令
04-Docker常用命令 启动类命令 启动docker systemctl start docker停止docker systemctl stop docker重启docker systemctl restart docker查看docker状态 systemctl status docker开机启动docker systemctl enable docker帮助类命令 查看docker版本 docker version查…...
数字化转型中的供应链管理优化
在当今全球化和数字化的浪潮下,企业供应链管理面临着前所未有的挑战和机遇,企业在数字化转型过程中,如何优化供应链管理成为提升竞争力的关键。通过应用先进技术如RPA机器人流程自动化、大数据分析、物联网等,企业可以显著提高物流…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
Python爬虫实战:研究feedparser库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...
关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...
高防服务器能够抵御哪些网络攻击呢?
高防服务器作为一种有着高度防御能力的服务器,可以帮助网站应对分布式拒绝服务攻击,有效识别和清理一些恶意的网络流量,为用户提供安全且稳定的网络环境,那么,高防服务器一般都可以抵御哪些网络攻击呢?下面…...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...
Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?
Redis 的发布订阅(Pub/Sub)模式与专业的 MQ(Message Queue)如 Kafka、RabbitMQ 进行比较,核心的权衡点在于:简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...
