如何理解swift中的delegate

来源:互联网 发布:软件制作平台 编辑:程序博客网 时间:2024/05/16 14:04

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 = trackergame.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

https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Protocols.html#//apple_ref/doc/uid/TP40014097-CH25-ID267

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 cad填充图案拾取不了点怎么办 cad填充图案太密怎么办 桃木葫芦挂件裂口了怎么办 皮肤被太阳晒伤变黑怎么办 皮肤又粗又黑该怎么办 盆栽红薯长疯了怎么办 四叶草叶子发黄怎么办 美篇不想让别人看到怎么办 黑魂3暗灵入侵怎么办 问道手游账号忘了怎么办 问道手游密码忘了怎么办 毒蚂蚁咬了红肿怎么办 电脑开机后有电流声怎么办 小学生阅读方面不会总结怎么办 天龙八部手游转职装备怎么办 投简历没回应该怎么办? 开车开的腰疼怎么办 开车腰疼怎么办吃什么 58简历投错了怎么办 开了一天车腰疼怎么办 开车腰疼怎么办怎么解决好 球球大作战找不到主界面怎么办 在QQ上找不到主界面怎么办 mac地址被过滤了怎么办 续贷声明含非法字符怎么办 辞职老板不给结工资怎么办 辞职后老板不发工资怎么办 联想手机不自带系统升级怎么办 苹果6玩崩坏3卡怎么办 机票名字打错了怎么办? 安装软件后显示名字乱码怎么办 户口上民族错了怎么办 改名字后行驶证怎么办 眼角撞到了肿了怎么办 想不想修真邪气怎么办 进户门比房间门低怎么办 吃了药反胃想吐怎么办 药吃了胃难受怎么办 吃了牙痛药胃痛怎么办 吃了药刺激胃怎么办 吃凉的刺激到胃怎么办