转义闭包无法捕获swift5中正在变化的self(协议/扩展)参数

转义闭包无法捕获swift5中正在变化的self(协议/扩展)参数,swift5,Swift5,我已尝试在swift 5中更新此链接。 但我在更新方面有一个问题 这是错误行: UIView.animate(withDuration: 0.2) { self.transform = CGAffineTransform(rotationAngle: radians) } 您看到的错误是因为: 协议可旋转可以通过值(struct)类型实现;及 在协议扩展中实现的函数突变旋转(弧度:,动画:)包含一个转义闭包,用于捕获self 值类型在赋值

我已尝试在swift 5中更新此链接。 但我在更新方面有一个问题

这是错误行:

UIView.animate(withDuration: 0.2)
        {
            self.transform = CGAffineTransform(rotationAngle: radians)
        }

您看到的错误是因为:

  • 协议
    可旋转
    可以通过值(
    struct
    )类型实现;及
  • 在协议扩展中实现的函数
    突变旋转(弧度:,动画:)
    包含一个转义闭包,用于捕获
    self
  • 值类型在赋值时被复制(至少有效地复制),所以如果闭包捕获了可变值类型,那么哪一个副本被变异?早期的Swift有一个折衷的语义,它在大多数时候做了预期的事情,但在其他时候却产生了令人困惑的结果。此后,Swift对解决这一问题施加了更大的限制,早期的Swift变更建议解释了这些问题,并在Swift 3中实施

    Rotatable
    协议可以通过值类型来实现,但在您转换的代码中,它仅用于参考类型
    UIView
    ,并且该代码在Swift 2中可以正常工作

    在当前Swift中,一个解决方案是将可旋转的
    限制为参考类型:

    protocol Rotatable : class { ... }
    
    这还需要删除所有使用
    mutable
    ——这些都是为了值类型兼容性。通过这些简单的更改,代码可以正常工作

    注意:如果原始作者在
    UIView
    扩展(
    extension-UIView:Rotatable{func-rotate(…}
    )中实现了协议,而不是在单独的协议扩展(
    extension-Rotatable{…}
    )中,那么代码今天仍然可以工作,没有任何更改

    如果希望通过值类型保持协议的可实现性,可以通过将实现移动到
    UIView
    扩展中来实现(如果希望,只需移动单个函数
    rotate(弧度:,动画:)
    ,因为其余函数同时适用于值和引用类型)


    HTH

    请在此处链接错误