具体来说,Swift 内存管理如何使用委托模式与选项一起工作?
由于习惯了用 Objective-C 编写委托模式,我的本能是让委托weak
。例如,在 Objective-C 中:
@property (weak) id<FooDelegate> delegate;
然而,在 Swift 中执行此操作并不是那么简单。
如果我们有一个看起来很普通的协议:
protocol FooDelegate {
func doStuff()
}
我们不能将这种类型的变量声明为弱:
weak var delegate: FooDelegate?
产生错误:
“weak”不能应用于非类类型“FooDelegate”
所以我们要么不使用关键字weak
,这允许我们使用structs
and enums
作为代表,或者我们将协议更改为以下内容:
protocol FooDelegate: class {
func doStuff()
}
这允许我们使用weak
,但不允许我们使用structs
or enums
.
如果我不让我的协议成为类协议,因此不要使用weak
对于我的变量,我正在创建一个保留周期,对吗?
是否有任何可以想象的原因,为什么任何打算用作委托协议的协议不应该是类协议,以便这种类型的变量可以weak
?
我主要是问,因为在授权部分Apple 关于 Swift 协议的官方文档 https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Protocols.html#//apple_ref/doc/uid/TP40014097-CH25-XID_415,他们提供了一个非类协议和用作其类的委托的非弱变量的示例:
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 = [Int](count: finalSquare + 1, repeatedValue: 0)
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)
}
}
我们是否应该将此视为 Apple 认为我们应该使用结构体作为委托的暗示?或者这只是一个糟糕的例子,实际上,委托协议应该声明为仅类协议,以便委托对象可以持有对其委托的弱引用?