Je ne sais pas ce qui se passe ici, cela semble être assez simple. J'ai un protocole qui var mutable, une extension avec une fonction de mutation. Les choses chutent dans le testClass.testFunc , lorsque j'essaie d'utiliser mtkAnimQueAppend déclaré dans l'extension, j'obtiens cette erreur: "Impossible d'utiliser un membre en mutation sur une valeur immuable: 'self' est immuable.
protocol MTKAnimateValueDelegate {
var mtkAnimQue:[MTKAnimateValue]? {get set}
}
extension MTKAnimateValueDelegate {
///Adds element to que
mutating func mtkAnimQueAppend(element:MTKAnimateValue) {
if mtkAnimQue != nil {
mtkAnimQue?.append(element)
} else {
mtkAnimQue = [element]
}
}
}
class testClass: MTKAnimateValueDelegate {
var mtkAnimQue:[MTKAnimateValue]?
func testFunc() {
var animValue = MTKAnimateValue(fromValue: 10, toValue: 20, inSeconds: 2)
animValue.isAnimating = true
mtkAnimQueAppend(animValue) //ERROR: "Cannot use mutating member on immutable value: 'self' is immutable
}
}
Le problème est que, dans le protocole, vous marquez la fonction comme étant en mutation, ce que vous devez faire si vous souhaitez utiliser le protocole sur une structure. Cependant, le self qui est passé à testFunc
est immuable (c'est une référence à une instance de la classe) et qui déclenche le compilateur. Cela aurait du sens si testClass était en fait une structure et que vous pouviez faire muter la fonction pour résoudre le problème.
Je peux voir deux solutions:
faire la classe de protocole uniquement
protocol MTKAnimateValueDelegate: class { ...
Faites de testClass une structure et marquez testFunc comme étant en mutation.
Quoi qu'il en soit, je pense que c'est un bug qui doit être signalé à Apple.
Modifier
self
func testFunc() {
var animValue = MTKAnimateValue(fromValue: 10, toValue: 20, inSeconds: 2)
animValue.isAnimating = true
var mutableSelf = self
mutableSelf.mtkAnimQueAppend(animValue)
}
Puisque mutableSelf
est une référence, tout changement apporté par la fonction de mutation sera toujours reflété dans l'état de self
.