swift delegate 从开始到放弃
Delegate 由开始到放弃这里是官网链接,毕竟官网更加权威 说说协议(protocal)先来看一下官方的定义
熟悉java的开发者,在看完协议的定义以后,应该会觉得和java中的接口(interface)极为相似。java中接口用于定义类的实现,解耦调用类和被调用类,一个接口允许有多个实现。 总之,protocal就像是一纸合同,所有遵循(conform)了该合同的对象都必须实现该合同中的必须实现的内容 下面简单讲一下协议的使用 //声明一份协议 protocol SomeProtocol { //在这里定义协议的具体内容 } //一个对象可以遵循多个协议 struct SomeStructure: FirstProtocol,AnotherProtocol { } //如果类有父类,则父类在冒号后的第一个位置,然后才是协议,彼此用分号隔开 class SomeClass: SomeSuperclass,FirstProtocol,AnotherProtocol { // class definition goes here } 协议中属性的声明
//声明协议,该协议要求能够满足一个只读属性fullName protocol FullyNamed { var fullName: String { get } } //简单的实现 struct Person: FullyNamed { var fullName: String } let john = Person(fullName: "John Appleseed") // john.fullName 是"John Appleseed" //稍复杂的实现,返回姓+名 class Starship: FullyNamed { var prefix: String? var name: String init(name: String,prefix: String? = nil) { self.name = name self.prefix = prefix } var fullName: String { return (prefix != nil ? prefix! + " " : "") + name } } var ncc1701 = Starship(name: "Enterprise",prefix: "USS") // ncc1701.fullName is "USS Enterprise" 协议中方法的声明 protocol RandomNumberGenerator { //方法体,无需大括号 func random() -> Double } //实现类 class LinearCongruentialGenerator: RandomNumberGenerator { var lastRandom = 42.0 let m = 139968.0 let a = 3877.0 let c = 29573.0 func random() -> Double { lastRandom = ((lastRandom * a + c).truncatingRemainder(dividingBy:m)) return lastRandom / m } } //若实现对象为enum或struct,则对对象内数据有修改的方法应该标注为为mutating protocol Togglable { mutating func toggle() } enum OnOffSwitch: Togglable { case off,on mutating func toggle() { switch self { case .off: self = .on case .on: self = .off } } } 进入Delegation还是先看一下官方的定义
下面我们举一个具体的例子来说明委托 具体的实现如下:
因为委托是通过协议来实现的,所以一个委托可以有多个具体的实现,这样就降低了委托方和被委托方彼此之间的耦合。 这里在贴上官网上的代码例子 协议 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) } 实现第一个协议的委托类,委托另一个类来判断游戏是否结束了 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") } } delegate使用于需要回调的方法中。这样,被委托对象在不知道委托对象的情况下完成某些职责。委托对象根据被委托对象返回的信息选择后续如何执行。事实上,delegate在很大程度上类似于closure。只是delegate通过protocal的形式使结构更加清晰,可复用性更高,降低耦合度。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |