ここで何が起こっているのかわかりませんが、これはかなり簡単なはずです。可変関数、可変機能を備えた拡張機能を備えたプロトコルがあります。拡張機能で宣言されたmtkAnimQueAppendを使用しようとすると、testClass.testFuncで問題が発生します。このエラーが発生します。 "不変の値には変更メンバーを使用できません: 'self'は不変です。
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
}
}
問題は、プロトコルで関数をミューティングとしてマークすることです。これは、構造体でプロトコルを使用する場合に行う必要があります。ただし、testFunc
に渡されるselfは不変(クラスのインスタンスへの参照)であり、コンパイラーを起動します。これは、testClassが実際に構造体であり、関数を変更して問題を解決できる場合に意味があります。
私は2つの回避策を見ることができます:
プロトコルクラスのみを作成する
protocol MTKAnimateValueDelegate: class { ...
TestClassを構造体にし、testFuncを変更可能としてマークします。
いずれにせよ、これはアップルに報告する必要があるバグだと思います。
編集
self
の可変コピーを作成することですfunc testFunc() {
var animValue = MTKAnimateValue(fromValue: 10, toValue: 20, inSeconds: 2)
animValue.isAnimating = true
var mutableSelf = self
mutableSelf.mtkAnimQueAppend(animValue)
}
mutableSelf
は参照であるため、変更関数による変更はすべてself
の状態に反映されます。