我正在一個結構中創建一個類來創建一個在 Apple Watch 和配對手機之間發送資訊的計時器。嘗試使用按鈕運行計時器時出現錯誤:
不允許部分應用“變異”方法
我創建類的方式如下:
import SwiftUI
struct ContentView: View {
//Timer to send information to phone
var timerLogic: TimerLogic!
var body: some View {
Button(action: startTimer, //"partial application of 'mutating' method is not allowed"
label: {
Image(systemName: "location")
})
}
// Class with the timer logic
class TimerLogic {
var structRef: ContentView!
var timer: Timer!
init(_ structRef: ContentView) {
self.structRef = structRef
self.timer = Timer.scheduledTimer(
timeInterval: 3.0,
target: self,
selector: #selector(timerTicked),
userInfo: nil,
repeats: true)
}
func stopTimer() {
self.timer?.invalidate()
self.structRef = nil
}
// Function to run with each timer tick
@objc private func timerTicked() {
self.structRef.timerTicked()
}
}
mutating func startTimer() {
self.timerLogic = TimerLogic(self)
}
// Function to run with each timer tick, this can be any action
func timerTicked() {
let data = ["latitude": "\(location.coordinate.latitude)", "longitud": "\(location.coordinate.longitude)"]
connectivity.sendMessage(data)
}
}
可能解決錯誤的最接近的解決方案是這個還是有另一個?
uj5u.com熱心網友回復:
SwiftUIView不應該有mutating屬性/功能。相反,他們應該使用屬性包裝像@State與@StateObject國有。
除了mutating功能之外,您還與 SwiftUI 的原則發生了沖突。例如,您永遠不應該嘗試保留對 a 的參考View并在其上呼叫函式。視圖在 SwiftUI 中是暫時的,如果您需要回呼它們,不應期望它們再次存在。此外,SwiftUI 傾向于與 Combine 攜手并進,這將非常適合在您的Timer代碼中實作。
這可能是一個合理的重構:
import SwiftUI
import Combine
// Class with the timer logic
class TimerLogic : ObservableObject {
@Published var timerEvent : Timer.TimerPublisher.Output?
private var cancellable: AnyCancellable?
func startTimer() {
cancellable = Timer.publish(every: 3.0, on: RunLoop.main, in: .default)
.autoconnect()
.sink { event in
self.timerEvent = event
}
}
func stopTimer() {
cancellable?.cancel()
}
}
struct ContentView: View {
//Timer to send information to phone
@StateObject var timerLogic = TimerLogic()
var body: some View {
Button(action: timerLogic.startTimer) {
Image(systemName: "location")
}
.onChange(of: timerLogic.timerEvent) { _ in
timerTicked()
}
}
// Function to run with each timer tick, this can be any action
func timerTicked() {
print("Timer ticked...")
//...
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/347605.html
上一篇:如何洗掉工具列?
