如何理解swift中的delegate
Delegation翻译为代理或者委托,是一种设计模式。顾名思义,使class或struct能够将某些职责移交给其他类型的实例。
该设计模式通过定义一个封装(包含)delegate的protocol(协议)来实现,从而保证这个代理囊括所定义的功能。Delegation可用于响应特定操作,或者从外部源检索数据,而不需要知道该源的基础类型。
(一)这里举一个dice-based(摇骰子)的游戏作为例子:
定义两个protocol:
DiceGame:被所有需要骰子的游戏采用;
DiceGameDelegate:被所有需要track(跟踪)游戏过程的类型所采用;
protocol DiceGame {
var dice: Dice { get }
func play()
}
protocol DiceGameDelegate {
func gameDidStart(_ game: DiceGame)
func game(_ game: DiceGame, didStartNewTurnWithDiceRoll diceRoll: Int)
func gameDidEnd(_ game: DiceGame)
}
(二)这里有一个Snakes and Ladders(蛇与梯子)的游戏,使用了筛子所以采用DiceGame协议(protocol),并且设置了一个DiceGameDelegate的代理来track游戏的过程。想具体了解Snakes and ladders这个游戏过程的可以参考[Control flow 中的break]。(https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/ControlFlow.html#//apple_ref/doc/uid/TP40014097-CH9-ID137)
class SnakesAndLadders: DiceGame {
let finalSquare = 25
let dice = Dice(sides: 6, generator: LinearCongruentialGenerator())
var square = 0
var board: [Int]
init() {
board = Array(repeating: 0, count: finalSquare + 1)
board[03] = +08; board[06] = +11; board[09] = +09; board[10] = +02
board[14] = -10; board[19] = -11; board[22] = -02; board[24] = -08
}
var delegate: DiceGameDelegate?
func play() {
square = 0
delegate?.gameDidStart(self)
gameLoop: while square != finalSquare {
let diceRoll = dice.roll()
delegate?.game(self, didStartNewTurnWithDiceRoll: diceRoll)
switch square + diceRoll {
case finalSquare:
break gameLoop
case let newSquare where newSquare > finalSquare:
continue gameLoop
default:
square += diceRoll
square += board[square]
}
}
delegate?.gameDidEnd(self)
}
}
(三)
class DiceGameTracker: DiceGameDelegate {
var numberOfTurns = 0
func gameDidStart(_ game: DiceGame) {
numberOfTurns = 0
if game is SnakesAndLadders {
print("Started a new game of Snakes and Ladders")
}
print("The game is using a \(game.dice.sides)-sided dice")
}
func game(_ game: DiceGame, didStartNewTurnWithDiceRoll diceRoll: Int) {
numberOfTurns += 1
print("Rolled a \(diceRoll)")
}
func gameDidEnd(_ game: DiceGame) {
print("The game lasted for \(numberOfTurns) turns")
}
}
DiceGameTracker实现了所有DiceGameDelegate中所要求的三个方法,从而达到记录整个游戏过程的目的。
(四)下面是整个游戏实际运行的过程:
let tracker = DiceGameTracker()
let game = SnakesAndLadders()
game.delegate = tracker
game.play()
// Started a new game of Snakes and Ladders
// The game is using a 6-sided dice
// Rolled a 3
// Rolled a 5
// Rolled a 4
// Rolled a 5
// The game lasted for 4 turns
分别定义了一个实现DiceGameDelegate的tracker和一个游戏game,将game的代理设置为tracker,当game调用play函数的时候,track会代理地记录下游戏的整个过程。
参考:
The swift programming language
如何理解swift中的delegate的更多相关文章
- [翻译]理解Swift中的Optional
原文出处:Understanding Optionals in Swift 苹果新的Swift编程语言带来了一些新的技巧,能使软件开发比以往更方便.更安全.然而,一个很有力的特性Optional,在你 ...
- 理解Swift中map 和 flatMap对集合的作用
map和flatMap是函数式编程中常见的概念,python等语言中都有.借助于 map和flapMap 函数可以非常轻易地将数组转换成另外一个新数组. map函数可以被数组调用,它接受一个闭包作为參 ...
- swift中第三方网络请求库Alamofire的安装与使用
swift中第三方网络请求库Alamofire的安装与使用 Alamofire是swift中一个比较流行的网络请求库:https://github.com/Alamofire/Alamofire.下面 ...
- swift 中delegate的使用
今天写了delegate,遇到以下问题: 这里protocol的写法有问题,如果delegate指向一个实现了某个协议对象的引用,在oc里是这样写delegate的类型 id<protocol& ...
- 在OC中调用Swift类中定义delegate出现:Property 'delegate' not found on object of type ...
找了许久没找到答案, 在下面的链接中, 我解决了这个问题: http://stackoverflow.com/questions/26366082/cannot-access-property-of- ...
- swift中的?和!理解
本文转载至 http://www.cnblogs.com/dugulong/p/3770367.html 首先贴cocoachina上某位大大的帖子: Swift语言使用var定义变量,但和别 ...
- [Swift]UIAlertController 以及 Swift 中的闭包和枚举
原文地址:http://blog.callmewhy.com/2014/10/08/uialertcontroller-swift-closures-enum/ 在 iOS8 的 SDK 中, UIK ...
- 怎么理解js中的事件委托
怎么理解js中的事件委托 时间 2015-01-15 00:59:59 SegmentFault 原文 http://segmentfault.com/blog/sunchengli/119000 ...
- 窥探Swift之使用Web浏览器编译Swift代码以及Swift中的泛型
有的小伙伴会问:博主,没有Mac怎么学Swift语言呢,我想学Swift,但前提得买个Mac.非也,非也.如果你想了解或者初步学习Swift语言的话,你可以登录这个网站:http://swiftstu ...
随机推荐
- java8泛型
目录 1,泛型中的相关操作符 2,泛型基本使用示例 3,通配符 3.1, T和?的区别 3.2,上下界通配符 4, 附加约束(&) 泛型,也就是将类型参数化,然后在使用类或者方法的时候可以 ...
- Golang 接口与反射知识要点
目录 Golang 接口与反射知识要点 1. 接口类型变量 2. 类型断言 3. 鸭子类型 4. 反射机制 5. reflect 包 TypeOf().ValueOf() Type().Kind() ...
- Python爬虫(三):BeautifulSoup库
BeautifulSoup 是一个可以从 HTML 或 XML 文件中提取数据的 Python 库,它能够将 HTML 或 XML 转化为可定位的树形结构,并提供了导航.查找.修改功能,它会自动将输入 ...
- Zabbix监控方案-官方最新4.4版本
Zabbix 2019/10/12 Chenxin 参考 https://www.zabbix.com/documentation/4.0/zh/manual https://baike.baidu. ...
- spring5 源码深度解析----- Spring事务 是怎么通过AOP实现的?(100%理解Spring事务)
此篇文章需要有SpringAOP基础,知道AOP底层原理可以更好的理解Spring的事务处理. 自定义标签 对于Spring中事务功能的代码分析,我们首先从配置文件开始人手,在配置文件中有这样一个配置 ...
- UnicodeDecodeError: 'gbk' codec can't decode byte 0xae in position 357: illegal multibyte sequence 错误解决方法(已解决)
今天在搭建数据驱动测试框架的时候遇到这个错误: 好在我英语水平还不错(也就六级水平吧),根据英文提示说是多字节数据顺序是非法的 顺着错误往上找发现 File "C:\Users\Mr雷的电脑 ...
- 包名targetPackage和目录名targetProject
generatorConfig.xml中的 <javaModelGenerator targetPackage="edu.cn.pojo" targetProject=&qu ...
- bugku 程序员本地网站
提示从本地访问,怎样让服务器认为你是从本地进行访问的: 使用burp抓包并在包中进行修改加入X-Forwarded-For: 127.0.0.1 X-Forwarded-For: 简称XFF头,它代表 ...
- Redis开发与运维:数据迁移(下)
上一篇,有朋友留言redis-port,借此机会我尝试使用一下redis-port这个同步工具 redis-port 已编译版 https://github.com/CodisLabs/redis-p ...
- Qt5教程: (6) 菜单栏、工具栏、状态栏及核心控件
1. 新建QMainWindow工程 取消生成.ui文件 2. 菜单栏 在mainwindow.cpp中添加头文件 和 #include <QMenuBar> #include <Q ...