手把手带你在 Swift 中应用代理(Delegate)

简介: 本文讲的是手把手带你在 Swift 中应用代理(Delegate),什么是代理呢?在软件开发中,存在许多用于解决特定场景中的普遍问题的通用方案架构,这些所谓的“模板”,常被称为设计模式。
本文讲的是手把手带你在 Swift 中应用代理(Delegate),

什么是代理呢?在软件开发中,存在许多用于解决特定场景中的普遍问题的通用方案架构,这些所谓的“模板”,常被称为设计模式。

代理就是一种设计模式,它允许某个对象在特定事件发生时,向另一个对象发送消息。

试想对象 A 调用对象 B 来执行某项操作。该操作完成后,对象 A 理应感知到对象 B 已经完成了任务以便采取后续的其它必要操作,而代理模式便能帮助我们完成这样的要求!

为了更好地理解这个概念,我将用 Swift 写一个简单地应用来向你展示如何创建一个自定义代理来在类之间传递数据,首先,下载或 clone 初始项目 并运行看看吧!

你可以看到项目中有两个类,ViewController A 和 ViewController B。B 有两个视图,被点击时会修改 ViewController 的背景颜色,没什么复杂的概念,对吧?现在我们要想一个简单办法,来让类 A 的背景颜色也随着类 B 中的视图点击变化。

问题在于,这些视图是类 B 的一部分,并不能感知到类 A,所以我们要想办法使两个类建立起联系,这便是代理大展身手的地方。

我将实现过程分为了六个步骤,当你需要实现代理时可以依此作为参考。

第一步:在 ClassBVC 文件中找到 step 1 的注释,并添加如下代码

//MARK: step 1 Add Protocol here.

protocol ClassBVCDelegate: class {

func changeBackgroundColor(_ color: UIColor?)

}

首先我们需要创建一个协议(protocol),本例中,我们将在类 B 中创建这个协议,你可以根据实际需要来向协议中添加任意数量的方法。本例只添加了一个接收可选的 UIColor 实例(optional UIColor)为参数的简单方法。

在类名末尾添加 Delegate 并将其作为你的协议的名称是一个良好的习惯,本例中就是 ClassBVCDelegate。

第二步:在 ClassBVC 文件中找到 step 2 的注释,并添加如下代码

//MARK: step 2 Create a delegate property here.
weak var delegate: ClassBVCDelegate?

这里我们仅仅是为类添加了一个 delegate 属性,该属性必须遵循对应的协议,同时其应该被定义为可选的。同时,在声明属性时添加 weak 关键字来避免循环引用以及可能出现的内存泄露,如果你现在还不了解这是什么意思,也没关系,记着要加上这个关键字即可。

第三步:在 ClassBVC 文件中的 handleTap 方法中找到 step 3 的注释,并添加如下代码

//MARK: step 3 Add the delegate method call here.
delegate?.changeBackgroundColor(tapGesture.view?.backgroundColor)

你需要注意一件事,如果你现在运行程序,不论你点击哪个视图都不会看到有任何新增的表现,这是正常的,我想特别说明的是,尽管此时 delegate 属性仍未被赋值,但我们访问它的时候应用并没有崩溃,这正是因为我们将其定义为了可选类型。现在让我们把视线移动到 ClassAVC 文件中,并将其实现为代理。

第四步:在 ClassAVC 文件中找到 step 4 的注释,在类的类型后添加如下代码

//MARK: step 4 conform the protocol here.
class ClassAVC: UIViewController, ClassBVCDelegate {

现在 ClassAVC 便遵循了 ClassBVCDelegate 协议,你会发现编译器已经给了你一个“Type ‘ClassAVC does not conform to protocol ‘ClassBVCDelegate’”的错误了,这不过是因为你还没有实现协议中所规定的方法而已,类 A 遵循该协议时就像是和类 B 签下了一纸合约,合约规定“任何遵循该协议的类都 必须 实现规定的方法!”

注意:如果你有一定的 Objective-C 开发经验,你或许认为将该协议方法标记为可选就能消除这个错误了,但出乎我意料的是(或许你也感到惊讶),Swift 中并没有可选协议方法的概念。

第五步:在 prepare for segue 方法中找到 step 5 的注释,并添加

//MARK: step 5 create a reference of Class B and bind them through the prepareforsegue method.
if let nav = segue.destination as? UINavigationController, let classBVC = nav.topViewController as? ClassBVC {
classBVC.delegate = self
}

此处我们创建了一个 ClassBVC 的实例,并将 self 赋值给其 delegate 属性,self 是什么呢?self 就是实现了代理协议的 ClassAVC 实例!

第六步:最终,在 ClassAVC 中找到 step 6 的注释,实现协议中的方法。当你着手输入 func changeBackgroundColor 的时候,会发现编译器会出现相应的自动补全。在方法中你可以添加对应的实现,而本例中,我们仅仅是改变背景颜色,因此添加如下代码。

//MARK: step 6 finally use the method of the contract
func changeBackgroundColor(_ color: UIColor?) {
view.backgroundColor = color
}

现在,运行程序吧!

代理无处不在,你或许正在使用却毫无察觉,如果你曾经使用过 table view,那么你就用过代理模式,许多 UIKIT 和各种框架中的类都围绕着代理做文章,而代理主要解决了以下几个问题。

  • 避免了对象之间的强耦合。
  • 无需继承便可改变对象的行为和外观。
  • 使任务可以交付给任意对象。(译者注:即抽象,无需依赖于具体类型)

恭喜,你刚刚动手实现了一个自定义代理,我知道或许此时你想着的是,这么大费周折就为了实现这点事情?呃,如果你想成为一个 iOS 开发者,那么理解代理这种设计模式至关重要,你要时刻记住,代理模式中对象之间总是一对一关系。

如果你感到疑惑也不必担心,我也花了好些时间才弄明白其中的含义,这甚至是我在上 iOS 培训课时候的重点课题。所以放轻松,慢慢来,如果你想和我讨论讨论,欢迎来 Twitter 找我。

你可以在 这里 找到项目的完整代码。

感谢阅读!





原文发布时间为:2017年2月12日

本文来自云栖社区合作伙伴掘金,了解相关信息可以关注掘金网站。
目录
相关文章
|
7天前
|
存储 Swift iOS开发
使用Swift开发一个简单的iOS应用的详细步骤。
使用Swift开发iOS应用的步骤包括:创建Xcode项目,设计界面(Storyboard或代码),定义数据模型,实现业务逻辑,连接界面和逻辑,处理数据存储(如Core Data),添加网络请求(必要时),调试与测试,根据测试结果优化改进,最后提交至App Store或其它平台发布。
21 0
|
7天前
|
机器学习/深度学习 数据采集 TensorFlow
【Swift开发专栏】Swift与机器学习:构建智能应用
【4月更文挑战第30天】本文探讨了使用Swift开发机器学习应用,分为三个部分:机器学习基础(定义、类型及应用),Swift在机器学习中的作用(Swift for TensorFlow、Core ML及性能优势),以及实践技巧(数据预处理、特征工程、模型训练与部署、性能优化和用户界面集成)。通过学习,开发者能掌握构建智能应用的技能,利用Swift的性能和安全性提升应用效率。随着深入学习,开发者可探索更多高级特性和技术,如深度学习和复杂数据分析。
|
7天前
|
存储 API Swift
【Swift开发专栏】Swift函数与闭包的实战应用
【4月更文挑战第30天】本文介绍了 Swift 中函数和闭包的实战应用。首先,函数的基本使用包括定义、参数与返回值、函数类型以及高级技巧如嵌套函数。接着,讨论了闭包的语法,包括无名函数、作为函数参数、简写形式和尾随闭包。最后,展示了函数和闭包在实战中的应用,如排序过滤集合和处理异步任务的回调。
|
7天前
|
缓存 Swift UED
【Swift开发专栏】Swift应用的启动优化
【4月更文挑战第30天】本文介绍了Swift应用启动优化技巧,包括优化代码结构和资源加载。建议减少启动时加载的代码,采用延迟加载、分模块加载和懒加载策略;优化初始化代码,注意顺序、异步初始化和避免全局初始化。对于资源,压缩图片、使用矢量图和图片缓存可提升加载速度。文中还提供了实战案例,展示如何在代码中实施这些优化措施。
|
7天前
|
安全 Swift iOS开发
【Swift 开发专栏】Swift 与 UIKit:构建 iOS 应用界面
【4月更文挑战第30天】本文探讨了Swift和UIKit在构建iOS应用界面的关键技术和实践方法。Swift的简洁语法、类型安全和高效编程模型,加上与UIKit的紧密集成,使开发者能便捷地创建用户界面。UIKit提供视图、控制器、布局、动画和事件处理等功能,支持灵活的界面设计。实践中,遵循设计原则,合理组织视图层次,运用布局和动画,以及实现响应式设计,能提升界面质量和用户体验。文章通过登录、列表和详情界面的实际案例展示了Swift与UIKit的结合应用。
|
7天前
|
缓存 算法 Swift
【Swift 开发专栏】Swift 应用的性能优化技巧
【4月更文挑战第30天】本文探讨了Swift应用性能优化,强调理解性能瓶颈、针对性优化和平衡性能与代码质量的重要性。提出优化技巧,包括选择合适数据结构、避免不必要的对象创建、使用缓存、优化算法、减少计算、管理内存、利用多核处理、优化网络请求和界面渲染。通过实际案例分析证明了这些方法能有效提升应用性能和用户体验。开发者应持续关注新技术和方法,以适应不断提升的性能要求。
|
7天前
|
存储 安全 Swift
【Swift 开发专栏】使用 Swift 开发一个简单的 iOS 应用
【4月更文挑战第30天】本文介绍了使用 Swift 开发简单 iOS 待办事项应用的步骤。首先,阐述了 iOS 开发的吸引力及 Swift 语言的优势。接着,详细说明了应用的需求和设计,包括添加、查看和删除待办事项的功能。开发步骤包括创建项目、界面搭建、数据存储、功能实现,并提供了相关代码示例。最后,强调了实际开发中需注意的细节和优化,旨在帮助初学者掌握 Swift 和 iOS 开发基础。
|
4月前
|
监控 Swift iOS开发
局域网计算机监控软件中利用Swift构建iOS端的移动监控应用
在局域网计算机监控软件的开发中,构建iOS端的移动监控应用是一项关键任务。本文将介绍如何利用Swift语言实现这一目标,通过多个代码示例展示关键功能的实现。
225 1
|
6月前
|
JavaScript 前端开发 PHP
用swift开发ios移动端app应用初体验
直接跟着 apple 官方的 SwiftUI 教程跑的,写惯了 javascript 奔放的代码,很多语法理解起来还是有点费劲
59 1
|
存储 前端开发 中间件
使用 Swift 搭建一个 HTTP 代理
我将通过这篇文章详述一下如何用 Swift 搭建一个 HTTP 代理服务器。本文将使用 Hummingbird 作为服务端的基本HTTP框架,以及使用 AsyncHTTPClient 作为 Swift 的 HTTP 客户端来请求目标服务。
216 0

相关课程

更多