如何理解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 ...
随机推荐
- redis列表底层实现之一——链表
注意标题中的“之一”,那么什么情况下,列表会使用链表作为其数据结构呢? 答案就是——列表键包含了大量的元素,或者列表中包含的元素都是比较长的字符串. Ok,由于链表大家都比较熟悉,接下来就直接给出链表 ...
- Kafka 学习笔记之 High Level Consumer相关参数
High Level Consumer相关参数 自动管理offset auto.commit.enable = true auto.commit.interval.ms = 60*1000 手动管理o ...
- 使用 Chrome 对长网页(知乎、微信公众号文章)进行完整截图
当需要对一个较长的网页进行完整截图时,可以直接使用谷歌浏览器(Chrome)自带的截图功能完成,不需要依赖第三方截图软件. 1. 打开网页 以微信公众号的页面作为示例:https://mp.weixi ...
- 《Java语言程序设计》编程练习8.9(游戏:#字游戏)
8.9 (游戏:#字游戏)在并字游戏中,两个玩家使用各自的标志(一方用X则另一方就用O),轮流填写3x3的网格中的某个空格.当一个玩家在网格的水平方向.垂直方向或者对角线方向上出 现了三个相同的X或三 ...
- 你也可以写聊天程序 - C# Socket学习1
简述 我们做软件工作的虽然每天都离不开网络,可网络协议细节却不是每个人都会接触和深入了解.我今天就来和大家一起学习下Socket,并写一个简单的聊天程序. 一些基础类 首先我们每天打开浏览器访问网页信 ...
- uni-app h5端跳转到底部导航栏的时候使用方法uni.switchTab跳转刷新页面更新数据
h5端的uni-app项目 需求:uni-app h5端跳转到底部导航栏的时候使用方法uni.switchTab跳转刷新页面更新数据 百度的方法如下: uni.switchTab({ url: '/p ...
- Spring Cloud之Zuul
API网关是一个更为智能的应用服务器,它的存在就像是整个微服务架构系统的门面一样,所有的外部客户端访问都需要经过它来进行调度和过滤.它除了要实现请求路由.负载均衡.校验过滤等功能之外,还需要更多能力, ...
- LeetCode_682-Baseball Game
给定一个字符串列表,字符串包含整数,’+’,’D’,’C’,整数代表一个分数,’+’代表后两个有效分数的和,’D’代表后一个有效分数的两倍,’C’代表删除后一个有效的分数值,最后求所有有效分数的和.例 ...
- DataTableHelper.cs 将DataTable转换为List,将List转换为DataTable的实现类
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- 程序猿的产品思考:2C与2B产品思维的区别
原创/朱季谦 我最早接触到互联网产品的时候,听到最多的,是做产品要有用户思维,即站在用户角度去看待产品.这个先入为主的概念,在很长一段时间里,都被我效作经典.然而也在很长一段时间里,我竟混淆了其中 ...