protocols - Swift 2 在协议(protocol)扩展 "Cannot use mutating member on immutable value: ' self' 中使用变异函数时出错

标签 protocols swift2 ios9 swift-extensions swift-protocols

不确定这里发生了什么,这看起来应该很简单。我有一个可变变量的协议(protocol),一个带有可变函数的扩展。 testClass.testFunc 中的事情很糟糕,当我尝试使用扩展中声明的 mtkAnimQueAppend 时,我收到此错误:“无法在不可变上使用变异成员值:“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
  }

}

最佳答案

问题是,在协议(protocol)中,您将函数标记为变异,如果您想在结构上使用协议(protocol),则需要这样做。然而,传递给 testFunc 的 self 是不可变的(它是对该类实例的引用),这会导致编译器崩溃。如果 testClass 实际上是一个结构体,并且您可以使函数发生变化来解决问题,那么这是有意义的。

我可以看到两种解决方法:

  1. 仅指定协议(protocol)类

    protocol MTKAnimateValueDelegate: class { ...
    
  2. 将 testClass 设为结构体并将 testFunc 标记为可变。

无论如何,我认为这是一个需要向 Apple 报告的错误。

编辑

  • 另一种解决方法是制作 self 的可变副本
  • func testFunc() {
        var animValue = MTKAnimateValue(fromValue: 10, toValue: 20, inSeconds: 2)
        animValue.isAnimating = true
        var mutableSelf = self
        mutableSelf.mtkAnimQueAppend(animValue) 
      }
    

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

    关于protocols - Swift 2 在协议(protocol)扩展 "Cannot use mutating member on immutable value: ' self' 中使用变异函数时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33098884/

    相关文章:

    ios - 如何使 iOS 通用链接在 iframe 中工作

    swift - 协议(protocol)扩展初始化器

    swift - 多类型约束

    security - Saml 身份验证请求协议(protocol) ID

    ios - 从 TableView 拖放到 Swift 中的另一个 View

    ios - performSegueWithIdentifier 未按预期显示 View Controller

    swift - 在 Swift 中,为什么子类方法不能覆盖父类(super class)中协议(protocol)扩展提供的方法

    ios - 更新 iOS 8 -> iOS 9(新版本的 Swift)导致使用 Alamofire 的 REST API 问题(401 错误)

    ios - 通过导航栏的后退按钮传递 bool 值

    ios - 如何 unwindForSegue :towardsViewController: works?