[英]Escaping closure captures mutating 'self' parameter: struct
我有以下與 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
}
}
但是,我收到一個錯誤:
Escaping 閉包捕獲變異的“自我”參數
我知道將結構更改為 class 可以解決這個問題,但是有沒有辦法在結構中的 escaping 閉包中實際捕獲變異自我?
如您所見,快速解決方案是使用參考類型class 。 但為什么會這樣呢?
Swift 結構是值類型,因此它們是不可變的。 您可以將 function 標記為正在mutating
,以向編譯器指示 function 會變異該結構,但這實際上意味着什么?
考慮一個簡單的結構:
struct Counter {
var count
init(_ count: Int = 0)
{
self.count = count
}
mutating func increment() {
self.count+=1
}
}
現在,嘗試將 this 的一個實例分配給一個let
常量:
let someCounter = Counter()
someCounter.increment()
print(someCounter.count)
你會得到一個錯誤; 你需要使用var
。
var someCounter = Counter()
someCounter.increment()
print(someCounter.count)
當你調用一個mutating
func 時,實際發生的是一個新的Counter
被創建,新的count
被分配給someCounter
。 它實際上是在說someCounter = Counter(someCounter.count+1)
現在,想想如果你可以在 escaping 閉包中改變self
會發生什么 - 新的Counter
將在未來某個未指定的時間創建,但執行已經繼續。 更新someCounter
為時已晚。
正如您所發現的,使用class
的另一個優點是您可以使用ObservableObject
,這使得更新 SwiftUI 視圖更加容易。
我完成的解決方案:
import Foundation
import Combine
public final class IntervalTrigger: ObservableObject {
private let timeInterval: TimeInterval
@Published var value = false
public init(_ timeInterval: TimeInterval) {
self.timeInterval = timeInterval
}
public func toggle() {
value = true
let responseDate = Date().advanced(by: timeInterval)
OperationQueue.main.schedule(after: .init(responseDate)) { [weak self] in
self?.value = false
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.