提问者:小点点

Swift 2在协议扩展中使用变异函数出错”无法在不可变值上使用变异成员:“self”是不可变的


不确定这里发生了什么,这似乎应该是非常直接的。我有一个可变var的协议,一个带有可变函数的扩展。testClass. testFunc中的东西正在拉屎,当我尝试使用扩展中声明的mtkKinQueAppend时,我得到了这个错误:“不能在不可变值上使用可变成员:'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
  }

}

共1个答案

匿名用户

问题是,在协议中,您将函数标记为mutating,如果您想在结构上使用该协议,则需要这样做。但是,传递给testFunc的self是不可变的(它是对类实例的引用),这会触发编译器。如果testClass实际上是一个结构,并且您可以使函数发生突变以解决问题,这将是有意义的。

我可以看到两个工作:

>

  • 只创建协议类

    protocol MTKAnimateValueDelegate: class { ...
    

    将testClass设为结构体并将testFunc标记为突变。

    不管怎样,我认为这是一个需要向苹果公司报告的bug。

    编辑

    func testFunc() {
        var animValue = MTKAnimateValue(fromValue: 10, toValue: 20, inSeconds: 2)
        animValue.isAnimating = true
        var mutableSelf = self
        mutableSelf.mtkAnimQueAppend(animValue) 
      }
    

    由于mutableSelf是一个引用,因此变异函数所做的任何更改仍将反映在self的状态中。