转义闭包捕获变异的“self”参数:struct

Ric*_*hiy 3 struct closures class ios swift

我有以下与 SwiftUI 一起使用的代码:

import Foundation

public struct Trigger {
    public var value = false

    public mutating func toggle() {
        value = true
        let responseDate = Date().advanced(by: 3)

        OperationQueue.main.schedule(after: .init(responseDate)) {
            moveBack()
        }
    }

    private mutating func moveBack() {
        value = false
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,我收到错误:

转义闭包捕获变异的“self”参数

在此输入图像描述

我知道将结构更改为类可以解决这个问题,但是有没有办法在结构中的转义闭包中实际捕获变异的 self ?

Pau*_*w11 18

正如您所发现的,快速解决方案是使用引用类型,即。但为什么会这样呢?

Swift 结构体是值类型,因此它们是不可变的。您可以将函数标记为mutating向编译器指示函数会改变结构,但这实际上意味着什么?

考虑一个简单的结构:

struct Counter {
   var count

   init(_ count: Int = 0)
   {
       self.count = count
   }

   mutating func increment() {
       self.count+=1
   }
}
Run Code Online (Sandbox Code Playgroud)

现在,尝试将其实例分配给常量let

let someCounter = Counter()
someCounter.increment()
print(someCounter.count)
Run Code Online (Sandbox Code Playgroud)

你会得到一个错误;你需要使用一个var.

var someCounter = Counter()
someCounter.increment()
print(someCounter.count)
Run Code Online (Sandbox Code Playgroud)

当您调用 func 时实际发生的情况mutating是创建一个新函数Countercount,并将该新函数分配给someCounter. 它实际上是在说someCounter = Counter(someCounter.count+1)

self现在,想想如果你可以在逃逸闭包中进行变异,会发生什么- 新的Counter闭包将在未来某个未指定的时间创建,但执行已经继续进行。更新已经太晚了someCounter

正如您所发现的,使用 的另一个优点class是您可以使用ObservableObject,这使得更新 SwiftUI 视图变得更加容易。

  • 很好的解释。(已投票)。我本想尝试解释一下,但你抢先了我,而且可能比我做得更好。 (2认同)