iOS设计模式之委托模式核心原理与实战解析
CocoaTouch框架中大量使用委托模式,通过协议和id类型实现对象间的单向协作。委托模式与适配器模式高度相似,充当对象间的转换器。实现方式包括传统协议和Block,协议适合多次回调,Block适合一次性场景。
Cocoa Touch 框架在 iOS 开发中大量采用了委托(Delegation)这一设计模式。根据苹果官方的定义,delegate 就是委托模式在 iOS 环境下的具体实现形式——简单来说,它是一种让对象之间实现“单向通信”的协作机制。
为了真正掌握委托的核心原理,我们需要先理清几个基本概念。下面就从最基础的协议开始讲起。
(一)协议
在 Objective-C 中,协议对于熟悉 C++ 或 Java 的开发者而言,可以类比为抽象类或接口。协议只声明方法,不负责具体实现。其定义格式如下:
@protocol MyButtonDelegate@optional - (void) didPressButton; @end
其中 @protocol 是关键字,MyButtonDelegate 是协议名称,didPressButton 就是协议中声明的方法。注意这里使用了 @optional,表示该方法并非强制实现——这恰恰体现了委托模式的灵活性与扩展性。
(二)id 类型
id 是 Objective-C 中一个非常特殊的类型,它可以被视为一个能够指向任意对象的通用指针。它的底层定义如下:
typedef struct objc_class *Class;
typedef struct objc_object {
Class isa;
} *id;
换句话说,任何 Objective-C 对象本质上都是一个 objc_object 结构体,而 id 就是指向这个结构体的指针。正因为它可以指向任意类型的对象,所以委托对象通常被声明为 id 类型,这样调用方就无需关心具体是哪个对象实现了协议中的方法。
(三)适配器模式
在经典的设计模式分类中,并没有一个独立的“委托模式”。但仔细观察会发现,委托所做的工作与适配器模式高度相似。举一个生活中的例子:去香港出差时,发现笔记本电脑的插头无法插入墙上的插座——因为香港使用的是英式三脚插头。这时你需要一个转换器,先把插头转换成能插入的形状,然后才能正常通电。委托模式在很多场景下恰恰充当了这个“转换器”的角色,它让两个原本没有直接关联的对象能够协同工作,本质上实现了一种对象适配器。
(四)实例
现在我们动手编写一个自定义按钮组件,其功能与 UIButton 类似,但使用委托来通知点击事件。首先从 UIView 继承一个 MyButton 类。问题是:我们并不清楚未来谁会使用这个按钮,但可以确定的是,每个使用者都需要在按钮被按下时收到通知。也就是说,MyButton 需要向某个对象(Adaptee)发送“我被按下了”的消息。
适配过程的设计如下:
@protocol MyButtonDelegate@optional - (void) didPressButton; @end
这里的 MyButton 扮演了 Adapter 角色,它通过以下机制来调用 Adaptee 的方法:

图中的 Adaptee 可以是任意对象,只要它遵守了 MyButtonDelegate 协议。目前最常见的做法是将 RootViewController 作为 Adaptee,让它实现 didPressButton 方法,这样按钮点击时就能直接回调到控制器层面。
(五)委托模式的深入理解
除了传统的协议方式,委托模式还可以通过 Block 来实现。但需要注意的是,Block 更适合一次性回调的场景——例如网络请求完成后执行的代码。而传统的委托则更适合需要多次回调、或者需要区分多个回调方法的情况。两者各有适用的场景,具体选择哪种方式取决于实际需求。
游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。
同类文章
AWS RDS 数据库配置入门与基础操作指南
本文介绍了AWSRDS的基本概念与核心价值,即提供托管式关系数据库服务,简化运维。详细阐述了创建RDS实例的关键配置步骤,包括引擎选择、实例规格、存储与网络设置。最后,指导读者如何通过多种方式安全连接至数据库实例,并开始进行数据操作,为后续应用开发奠定基础。
PHP MVC中AJAX请求无法调用控制器方法的原因与解决方案
PHPMVC中AJAX请求返回整页HTML的常见原因是控制器方法未正确输出响应或未终止执行,导致框架渲染视图。解决方法是在控制器中设置JSON响应头、输出数据后调用exit()明确终止,同时前端使用小写url和dataType: "json "。
Go语言手动构造rsa.PublicKey:正确初始化大整数模数N完整指南
手动构造RSA公钥时,模数N为*big Int类型,不能直接使用超长十进制字面量,需通过SetString或UnmarshalText方法解析字符串。公钥指数E可直接赋值,推荐65537。生产环境应使用rsa GenerateKey生成密钥对,避免手动构造引发的安全和格式错误。
Go语言实现HTTP定时轮询监控多URL响应时间与状态检测
使用Go语言实现HTTP定时轮询监控,通过按行分割与Tab解析URL列表,避免闭包陷阱和nil指针,每个URL启动独立ticker安全并发请求,并配置超时控制与资源关闭,确保响应时间与状态码准确检测。
Tkinter中Label标签在主循环动态更新的正确方法
在Tkinter中正确动态更新标签的方法:将标签组件的textvariable参数绑定到一个StringVar变量,然后通过调用该变量的 set()方法更新其值,界面会自动刷新。这样避免直接修改text属性或调用update()。此做法实现数据与界面的解耦,代码更简洁,响应更及时,避免手动同步的闪烁,推荐做法。
- 热门数据榜
相关攻略
2026-07-10 06:41
2026-07-10 06:40
2026-07-10 06:39
2026-07-10 06:39
2026-07-10 06:39
2026-07-10 06:39
2026-07-10 06:39
2026-07-10 06:39
热门教程
- 游戏攻略
- 安卓教程
- 苹果教程
- 电脑教程

