You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用GCD时@ObservedObject变更后SwiftUI View未更新问题求助

问题根因
  • @Published 对值类型的触发条件是整个属性值发生替换,你当前修改的是nmea结构体内部mtw元组的子属性,属于对结构体的原地修改,不会触发@Published的更新通知,视图自然不会刷新。
  • 你当前是把所有文件内容一次性读取后集中处理,即使修复了通知触发问题,也只会看到最终一行数据的结果,看不到逐行更新的效果。
修复方案

1. 触发@Published更新通知

修改parseNMEA方法,先复制原有nmea结构体修改完成后,再整体赋值给nmea属性,触发值替换逻辑:

private func parseNMEA(fields: [String]){
    switch fields[0].slice(3, 5){
    case "MTW":
        // 先复制原有结构体,修改副本
        var updatedNMEA = nmea
        updatedNMEA.mtw.src = fields[0].slice(1, 2)
        updatedNMEA.mtw.timeStamp = Date()
        updatedNMEA.mtw.temp = Double(fields[1]) ?? 0
        updatedNMEA.mtw.units = "º" + fields[2]
        // 整体赋值,触发@Published通知
        nmea = updatedNMEA
        print("MTW: \(nmea.mtw)")
    default:
        print("Missing sentence: \(fields[0].slice(1, 2))")
        return
    }
}

2. 实现逐行更新效果

如果需要看到每一行数据处理后的视图更新,修改receiveNMEA方法,逐行调度到主线程处理,可增加短延迟方便观察过程:

private func receiveNMEA() {
    do {
        let path = Bundle.main.path(forResource: "reprex-input", ofType: "txt") ?? ""
        let message = try String(contentsOfFile: path, encoding: .utf8)
        // 拆分所有非空行
        let allLines = message.components(separatedBy: .newlines).filter { !$0.isEmpty }
        // 逐行延迟处理,间隔0.3秒方便观察更新效果
        for (lineIndex, line) in allLines.enumerated() {
            DispatchQueue.main.asyncAfter(deadline: .now() + Double(lineIndex) * 0.3) {
                self.handleSingleLine(line: line)
            }
        }
    } catch {
        print("Error:", error)
    }
}

// 新增单条数据处理方法
private func handleSingleLine(line: String) {
    var fields = line.components(separatedBy: ",")
    guard let lastField = fields.last else { return }
    let splitLast = lastField.components(separatedBy: "*")
    fields.removeLast()
    fields.append(contentsOf: splitLast)
    guard fields.count >= 2 else { return }
    let valid = checksum(message: line, checksum: fields.last ?? "")
    if valid {
        parseNMEA(fields: fields)
    }
}
适配TCP实时流场景

如果是TCP持续接收数据流的场景,不需要加延迟,每次收到一条完整的NMEA报文后,直接在主线程调用handleSingleLine处理即可,每收到一条有效数据视图就会自动刷新一次。

内容的提问来源于stack exchange,提问作者MarkCX

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 07:27:02