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

iOS Delegate模式

文章目录

  • 一、 Delegate 模式的概念
  • 二、Delegate 的实现步骤
    • 步骤 1: 定义一个协议(Protocol)
    • 步骤 2: 在主类中添加一个 delegate 属性
    • 步骤 3: 实现协议的类遵守协议并实现方法
    • 步骤 4: 设置 delegate
  • 三、Delegate 模式的特点
  • 四、Delegate 模式的常见场景
    • 1. 视图控制器与视图组件之间的通信
    • 2. 处理用户输入事件
    • 3. 自定义控件的回调
    • 4. 事件的传递与回调
    • 5. 解耦设计
    • 6. 常见框架与委托


一、 Delegate 模式的概念

  • 核心思想:一个对象定义协议(Protocol),让其他对象遵守协议并实现相关方法,最终将任务交给这些对象完成。
  • 使用场景:实现对象之间的事件回调、数据传递 和 解耦。

二、Delegate 的实现步骤

步骤 1: 定义一个协议(Protocol)

协议中声明了需要实现的方法。

@protocol MyDelegate <NSObject>
- (void)taskDidComplete;  // 定义协议方法
@end

步骤 2: 在主类中添加一个 delegate 属性

主类通过 weak 引用委托对象,避免循环引用。

@interface MyClass : NSObject
@property (nonatomic, weak) id<MyDelegate> delegate;  // 弱引用
- (void)startTask;
@end@implementation MyClass
- (void)startTask {NSLog(@"Task is starting...");// 模拟任务完成[self.delegate taskDidComplete];  // 调用委托对象的方法
}
@end

步骤 3: 实现协议的类遵守协议并实现方法

其他类通过遵守 MyDelegate 协议来实现任务。

@interface AnotherClass : NSObject <MyDelegate>
@end@implementation AnotherClass
- (void)taskDidComplete {NSLog(@"Task completed! Delegate notified.");
}
@end

步骤 4: 设置 delegate

主类通过 delegate 属性与实现类建立连接。

int main(int argc, const char * argv[]) {@autoreleasepool {MyClass *myClass = [[MyClass alloc] init];AnotherClass *anotherClass = [[AnotherClass alloc] init];myClass.delegate = anotherClass;  // 设置委托对象[myClass startTask];  // 触发任务}return 0;
}

输出:

Task is starting...
Task completed! Delegate notified.

三、Delegate 模式的特点

  • 解耦:实现者(委托对象)和调用者(主类)分离,降低耦合度。
  • 灵活性:不同的对象可以遵守协议,实现不同的逻辑。
  • 单向通信:委托对象实现协议方法,主类通过调用这些方法实现通信。

四、Delegate 模式的常见场景

1. 视图控制器与视图组件之间的通信

在 iOS 中,视图组件(如 UITableView、UITextField)通过 Delegate 与控制器通信,传递事件和数据。

示例:UITableView 的 Delegate 和 DataSource

UITableView 的事件(例如单元格选中、滚动)通过 UITableViewDelegate 和 UITableViewDataSource 协议回调到控制器中。

@interface ViewController () <UITableViewDelegate, UITableViewDataSource>
@property (nonatomic, strong) UITableView *tableView;
@end@implementation ViewController
- (void)viewDidLoad {[super viewDidLoad];self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds];self.tableView.delegate = self;self.tableView.dataSource = self;[self.view addSubview:self.tableView];
}// UITableViewDataSource 方法
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {return 10; // 返回行数
}- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];if (!cell) {cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];}cell.textLabel.text = [NSString stringWithFormat:@"Row %ld", (long)indexPath.row];return cell;
}// UITableViewDelegate 方法
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {NSLog(@"Selected row: %ld", (long)indexPath.row);
}
@end

2. 处理用户输入事件

委托模式在输入控件(如 UITextField 和 UITextView)中广泛使用,用于处理用户输入。

@interface ViewController () <UITextFieldDelegate>
@property (nonatomic, strong) UITextField *textField;
@end@implementation ViewController
- (void)viewDidLoad {[super viewDidLoad];self.textField = [[UITextField alloc] initWithFrame:CGRectMake(50, 100, 200, 40)];self.textField.borderStyle = UITextBorderStyleRoundedRect;self.textField.delegate = self;[self.view addSubview:self.textField];
}// UITextFieldDelegate 方法
- (BOOL)textFieldShouldReturn:(UITextField *)textField {[textField resignFirstResponder]; // 隐藏键盘return YES;
}
@end

3. 自定义控件的回调

在开发自定义控件时,可以定义一个 delegate,让外部类(通常是视图控制器)实现回调方法,处理控件的行为。

示例:自定义控件

@protocol CustomViewDelegate <NSObject>
- (void)customViewButtonWasTapped;
@end@interface CustomView : UIView
@property (nonatomic, weak) id<CustomViewDelegate> delegate;
@end@implementation CustomView
- (instancetype)initWithFrame:(CGRect)frame {self = [super initWithFrame:frame];if (self) {UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(50, 50, 100, 50)];[button setTitle:@"Tap Me" forState:UIControlStateNormal];[button setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];[button addTarget:self action:@selector(buttonTapped) forControlEvents:UIControlEventTouchUpInside];[self addSubview:button];}return self;
}- (void)buttonTapped {[self.delegate customViewButtonWasTapped];
}
@end

使用自定义控件:

@interface ViewController () <CustomViewDelegate>
@end@implementation ViewController
- (void)viewDidLoad {[super viewDidLoad];CustomView *customView = [[CustomView alloc] initWithFrame:self.view.bounds];customView.delegate = self;[self.view addSubview:customView];
}// CustomViewDelegate 方法
- (void)customViewButtonWasTapped {NSLog(@"Button was tapped in custom view.");
}
@end

4. 事件的传递与回调

在对象之间需要传递事件或执行回调时,Delegate 是一种常用方案。

  • 例如:网络请求完成后,将结果返回给调用者。
  • 例如:任务完成通知某个对象。

5. 解耦设计

Delegate 可以用于降低对象之间的耦合度。例如:

  • UITableView 和其数据源分离,控制器实现协议方法,而 UITableView 并不知道具体实现。
  • MVC 架构中,Controller 与 View 通过 Delegate 通信,解耦逻辑与界面代码。

6. 常见框架与委托

  • UITableViewDelegate / UITableViewDataSource:表格视图事件与数据源回调。
  • UICollectionViewDelegate / UICollectionViewDataSource:集合视图的数据源与事件处理。
  • UITextFieldDelegate:文本输入控件的事件回调。
  • NSURLSessionDelegate:网络请求结果的回调。
  • CLLocationManagerDelegate:位置服务的事件回调。

最佳实践:对于单一事件回调,推荐使用 Block,而对于复杂逻辑、多方法回调,使用 Delegate 模式更合适。

相关文章:

iOS Delegate模式

文章目录 一、 Delegate 模式的概念二、Delegate 的实现步骤步骤 1: 定义一个协议&#xff08;Protocol&#xff09;步骤 2: 在主类中添加一个 delegate 属性步骤 3: 实现协议的类遵守协议并实现方法步骤 4: 设置 delegate 三、Delegate 模式的特点四、Delegate 模式的常见场景…...

java-使用druid sqlparser将SQL DDL脚本转化为自定义的java对象

java-使用druid sqlparser将SQL DDL脚本转化为自定义的java对象 一、引言二、环境三、待解析的DDL四、解析后的对象结构五、完整的UT类六、控制台输出总结 一、引言 在日常开发中&#xff0c;有些需要对SQL进行解析的场景&#xff0c;比如读取表结构信息&#xff0c;生成文档、…...

React状态管理常见面试题目(一)

1. Redux 如何实现多个组件之间的通信?多个组件使用相同状态时如何进行管理? Redux 实现组件通信 Redux 是一个集中式的状态管理工具&#xff0c;通过共享一个全局 store 来实现多个组件之间的通信。 通信机制&#xff1a; 所有状态保存在 Redux 的全局 store 中。使用 ma…...

jenkins 出现 Jenkins: 403 No valid crumb was included in the request

文章目录 前言解决方式:1.跨站请求为找保护勾选"代理兼容"2.全局变量或者节点上添加环境变量3.&#xff08;可选&#xff09;下载插件 the strict Crumb Issuer plugin4.重启 前言 jenkins运行时间长了&#xff0c;经常出现点了好几次才能构建&#xff0c;然后报了Je…...

【前端面试】list转树、拍平, 指标,

这个题目涉及的是将一组具有父子关系的扁平数据转换为树形结构&#xff0c;通常称为“树形结构的构建”问题。类似的题目包括&#xff1a; 1. 组织架构转换 给定一个公司的员工列表&#xff0c;每个员工有 id 和 managerId&#xff0c;其中 managerId 表示该员工的上级。任务…...

游戏引擎学习第43天

仓库 https://gitee.com/mrxiao_com/2d_game 介绍运动方程 今天我们将更进一步&#xff0c;探索运动方程&#xff0c;了解真实世界中的物理&#xff0c;并调整它们&#xff0c;以创建一种让玩家感觉愉悦的控制体验。这并不是在做一个完美的物理模拟&#xff0c;而是找到最有趣…...

NVM:安装配置使用(详细教程)

文章目录 一、简介二、安装 nvm三、配置 nvm 镜像四、配置环境变量五、使用教程5.1 常用命令5.2 具体案例 六、结语 一、简介 在实际的开发和学习中可能会遇到不同项目的 node 版本不同&#xff0c;而出现的兼容性问题。 而 nvm 就可以很好的解决这个问题&#xff0c;它可以在…...

matlab测试ADC动态性能的原理

目录 摘要&#xff1a; 简介&#xff1a; 动态规范和定义 动态规格&#xff1a; 双面到单边的功率谱转换 摘要&#xff1a; 模数转换器&#xff08;adc&#xff09;代表了接收器、测试设备和其他电子设备中的模拟世界和数字世界之间的联系。正如本文系列的第1部分中所概述…...

PostgreSQL JSON/JSONB 查询与操作指南

PostgreSQL 提供了强大的 JSON 和 JSONB 数据类型及相关操作&#xff0c;适用于存储和查询半结构化数据。本文将详细介绍其常用操作。 1. 基础操作 1.1 JSON 属性访问 ->: 返回 JSON 对象中的值&#xff0c;结果为 JSON 格式。 SELECT {"a": {"b": 1…...

【Isaac Lab】Ubuntu22.04安装英伟达驱动

目录 1.1 禁用nouveau驱动 1.2 安装必要的依赖项 1.3 下载安装 1.4 查看是否安装成功 1.5 安装CUDA 1.5.1 下载 1.5.2 按照提示进行下载安装 1.5.3 添加环境变量 1.5.4 测试CUDA是否安装成功 1.1 禁用nouveau驱动 输入以下命令打开blacklist.conf文件 sudo vim /etc…...

JS,递归,处理树形数据组件,模糊查询树形结构数据字段

JS递归如何模糊查询树形结构数据,根据数据中的某一个字段值&#xff0c;模糊匹配 直接拿去使用就行 function filterTreeLabel(arr, label) {let result []arr.forEach((item) > {// if (String(item.POBJECT_NAME).toLowerCase().indexOf(label)!-1) {if (String(item.P…...

神州数码DCME-320 online_list.php 任意文件读取漏洞复现

0x01 产品描述: ‌神州数码DCME-320是一款高性能多业务路由器,专为多用户、多流量和多业务种类需求设计‌。它采用了...

nginx的内置变量以及nginx的代理

nginx的内置变量 客户端 命令含义$uri可以获取客户端请求的地址&#xff0c;包含主机和查询的参数$request_uri:获取客户端的请求地址&#xff0c;包含主机和查询参数。$host:请求的主机名&#xff0c;客户端—发送请求的url地址$http_user_agent获取客户端请求的浏览器和操作…...

ubuntu监测硬盘状态

安装smartmontools smartctl -l error /dev/sdk smartctl -i /dev/sda lshw -class disk smartctl -H /dev/sd 结果1&#xff1a; 结果2&#xff1a;PASSED&#xff0c;这表示硬盘健康状态良好 smartctl -a /dev/sdb sdk lsblk blkid 测试写入速度 time dd if/dev/zero of…...

3.2.1.2 汇编版 原子操作 CAS

基本原理说明 在 x86 和 ARM 架构上&#xff0c;原子操作通常利用硬件提供的原子指令来实现&#xff0c;比如 LOCK 前缀&#xff08;x86&#xff09;或 LDREX/STREX&#xff08;ARM&#xff09;。以下是一些关键的原子操作&#xff08;例如原子递增和比较交换&#xff09;的汇…...

InnoDB事务系统(二):事务的实现

事务隔离性由锁来实现。原子性、一致性、持久性通过数据库的 redo log 和 undo log 来完成。 redo log 称为重做日志&#xff0c;用来保证事务的原子性和持久性。undo log 用来保证事务的一致性。 有的 DBA 或许会认为 undo 是 redo 的逆过程&#xff0c;其实不然。redo 和 u…...

xdoj :模式匹配

模式匹配 题目描述&#xff1a; 接收信号中包含特定的信号模式&#xff0c;对接收信号进行检测&#xff0c;以统计特定模式出现的次数。 例如接收信号为 9 3 5 7 5 8 6 3 5 7 1 9 3 5 7&#xff0c;如果特定信号为 3 5 7&#xff0c;则接收信号中包含了 3 个特定模式。通过键…...

Redis的基本使用命令(GET,SET,KEYS,EXISTS,DEL,EXPIRE,TTL,TYPE)

目录 SET GET KEYS EXISTS DEL EXPIRE TTL redis中的过期策略是怎么实现的&#xff08;面试&#xff09; 上文介绍reids的安装以及基本概念&#xff0c;本章节主要介绍 Redis的基本使用命令的使用 Redis 是一个基于键值对&#xff08;KEY - VALUE&#xff09;存储的…...

LruCache(本地cache)生产环境中遇到的问题及改进

问题&#xff1a;单机qps增加时请求摘要后端&#xff0c;耗时也会增加&#xff0c;因为超过了后端处理能力&#xff08;最大qps&#xff0c;存在任务堆积&#xff09;。 版本一 引入LruCache。为了避免数据失效&#xff0c;cache数据的时效性要小于摘要后端物料的更新时间&…...

智慧公交指挥中枢,数据可视化 BI 驾驶舱

随着智慧城市的蓬勃发展&#xff0c;公共交通作为城市运营的核心枢纽&#xff0c;正朝着智能化和数据驱动的方向演进。通过整合 CAN 总线技术(Controller Area Network&#xff0c;控制器局域网总线)、车载智能终端、大数据分析及处理等尖端技术&#xff0c;构建的公交“大脑”…...

别再纠结SSR还是SSG了!用create-nuxt-app创建项目时,这个选择直接影响你的部署成本

Nuxt.js渲染模式深度解析&#xff1a;如何用create-nuxt-app做出高性价比技术选型 在2023年的前端技术栈中&#xff0c;Nuxt.js依然保持着作为Vue生态中最成熟SSR解决方案的领先地位。但很多团队在项目启动时&#xff0c;往往会在create-nuxt-app的配置界面陷入纠结——特别是当…...

OpenClaw多模型对比:Gemma-3-12b-it与Qwen在自动化任务中的表现

OpenClaw多模型对比&#xff1a;Gemma-3-12b-it与Qwen在自动化任务中的表现 1. 测试背景与实验设计 去年夏天&#xff0c;当我第一次尝试用OpenClaw自动化处理日常办公任务时&#xff0c;面对琳琅满目的大模型选项陷入了选择困难。作为个人开发者&#xff0c;既希望模型足够聪…...

EasyAnimateV5-7b-zh-InP模型在微信小程序中的应用:短视频生成功能实现

EasyAnimateV5-7b-zh-InP模型在微信小程序中的应用&#xff1a;短视频生成功能实现 1. 为什么要在微信小程序里集成视频生成能力 最近帮几个做社交内容的小团队做技术咨询&#xff0c;发现一个特别有意思的现象&#xff1a;用户发朋友圈、发群聊、发公众号时&#xff0c;对短…...

深度学习项目训练环境作品集:10类常见图像分类任务的统一训练模板与结果汇总

深度学习项目训练环境作品集&#xff1a;10类常见图像分类任务的统一训练模板与结果汇总 1. 环境准备与快速上手 深度学习项目训练往往需要复杂的环境配置&#xff0c;从框架安装到依赖库配置&#xff0c;整个过程耗时且容易出错。本镜像基于深度学习项目改进与实战专栏&…...

OpenClaw学术研究助手:Qwen3-14b_int4_awq自动生成文献综述

OpenClaw学术研究助手&#xff1a;Qwen3-14b_int4_awq自动生成文献综述 1. 为什么需要AI辅助文献调研 作为一名计算机视觉方向的研究生&#xff0c;我每周需要阅读数十篇论文来跟踪领域进展。传统文献调研方式存在几个痛点&#xff1a;首先&#xff0c;手动下载和整理PDF文件…...

Windows XP vs 98:XP.css双主题深度对比与选择指南

Windows XP vs 98&#xff1a;XP.css双主题深度对比与选择指南 【免费下载链接】XP.css A CSS framework for building faithful recreations of operating system GUIs. 项目地址: https://gitcode.com/gh_mirrors/xp/XP.css XP.css是一款强大的CSS框架&#xff0c;专为…...

GLM-OCR GPU算力优化实践:vLLM推理加速+令牌下采样,吞吐提升2.3倍

GLM-OCR GPU算力优化实践&#xff1a;vLLM推理加速令牌下采样&#xff0c;吞吐提升2.3倍 1. 项目背景与优化需求 GLM-OCR是一个基于GLM-V编码器-解码器架构构建的多模态OCR模型&#xff0c;专门为复杂文档理解而设计。这个模型集成了在大规模图文数据上预训练的CogViT视觉编码…...

千问3.5-27B效果实测:低质量扫描件文字区域检测与内容还原

千问3.5-27B效果实测&#xff1a;低质量扫描件文字区域检测与内容还原 1. 模型介绍 Qwen3.5-27B是Qwen官方发布的视觉多模态理解模型&#xff0c;具备强大的文本对话与图片理解能力。本镜像已在4张RTX 4090 D 24GB显卡环境下完成部署&#xff0c;提供中文Web对话界面、流式文…...

养鸡场规划:如何计算所需农场数量

在养鸡业中&#xff0c;如何高效地管理和规划农场的使用是一个关键问题。最近&#xff0c;我遇到了一位养鸡场主的需求&#xff0c;他需要根据每天的鸡出栏数据来计算所需农场的数量。今天&#xff0c;我们就来探讨如何通过编程解决这个问题。 问题背景 假设你有一个包含以下数…...

MTK6737平台LCD驱动移植保姆级教程:从供应商参数到开机Logo的完整避坑指南

MTK6737平台LCD驱动移植实战&#xff1a;从零构建显示系统的关键技术与避坑指南 在嵌入式设备开发中&#xff0c;显示系统作为人机交互的核心组件&#xff0c;其稳定性直接影响用户体验。MTK6737作为主流中端移动处理器平台&#xff0c;广泛应用于各类智能设备&#xff0c;而HX…...