在Swift 3.0中转义self(struct/enum)内部转义

aks*_*gde 11 ios swift swift2 swift3

在swift 2.2中,当它在一个变异函数中时,我们可以在一个闭包中变异一个struct或enum.但在swift 3.0中它已不再可能.我收到以下错误

闭包不能隐式捕获变异的自参数

这是一段代码片段,

struct Point {
    var x = 0.0, y = 0.0

    mutating func moveBy(x deltaX: Double, y deltaY: Double) {
        x += deltaX
        y += deltaY

        test { (a) -> Void in
            // Get the Error in the below line.
            self.x = Double(a)
        }

    }

    mutating func test(myClosure: @escaping (_ a: Double) -> Void) {
        myClosure(3)
    }
}
Run Code Online (Sandbox Code Playgroud)

我得到的值类型不应该是可变的.我有一些情况,当我收到API响应时,我必须在其中一个函数中修改结构中的一个变量.(完成关闭)

我在swift 2.2中做的是什么,不可能或者有没有办法实现这个目标?

Lio*_*Lio 9

问题是可以存储@escaping闭包以供以后执行:

逃离闭包

当闭包作为参数传递给函数时,闭包被称为转义函数,但在函数返回后调用....

闭包可以转义的一种方法是存储在函数外部定义的变量中....

由于闭包可以存储并存在于函数范围之外,因此闭包(self)中的struct/enum将被复制(它是一个值)作为闭包的参数.而且,如果它被允许变异,那么关闭可能会有一个旧的副本,导致不必要的结果.

那么,在回答你的问题时,你不能; 除非您能够删除"@escaping"(不是因为它是第三方API)


小智 0

是的,你可以做这样的事情。

struct Point {

    var x = 0.0, y = 0.0

    mutating func moveBy(x deltaX: Double, y deltaY: Double) {
        x += deltaX
        y += deltaY

        test { (a) -> Void in

            self.x = Double(a)
        }
    }

    mutating func test(myClosure: (_ a: Double) -> Void) {
        myClosure(3)
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 删除“@escaping”是一种方法,但在异步调用的情况下,您不能仅仅删除“@escaping”。所以这不是这个问题的有效选项。 (2认同)