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

Swift异步刷新令牌后@Published变量无法更新视图问题

问题诊断与解决:OAuth令牌刷新后视图不更新

问题背景

实现OAuth令牌刷新功能后,触发令牌刷新流程时,尽管后续请求成功获取数据,ViewModel中用@Published修饰的elements变量完成赋值,但视图始终不更新。日志显示assigning已执行,但视图无响应;无需刷新令牌时,代码运行正常。

原因分析

核心问题是并发线程不匹配:

  • @Published属性的赋值必须在MainActor(主线程)执行,才能正确触发视图更新通知。
  • 当触发401重试流程时,APIRequest.call的递归调用在后台异步线程执行,最终fetchElements中self.elements = response的赋值操作也处于后台线程,导致@Published的更新通知无法被视图正确接收。

解决方法

方法1:强制赋值操作在MainActor执行

修改MyViewModel的fetchElements方法,将状态更新逻辑包裹在MainActor.run中:

func fetchElements() async {
    print("fetching")

    do {
        let response = try await ElementsAction().call()
        print("assigning")
        await MainActor.run {
            self.elements = response
            self.error = nil
        }
    } catch let apiError as APIError {
        await MainActor.run {
            self.error = apiError
        }
    } catch {
        await MainActor.run {
            self.error = .unknown
        }
    }
}

方法2:给ViewModel异步方法标记MainActor

直接给fetchElements添加@MainActor修饰,确保整个方法的执行上下文在主线程:

@MainActor
func fetchElements() async {
    print("fetching")

    do {
        let response = try await ElementsAction().call()
        print("assigning")
        self.elements = response
        self.error = nil
    } catch let apiError as APIError {
        self.error = apiError
    } catch {
        self.error = .unknown
    }
}

验证说明

修改后,elements的赋值操作将在主线程执行,@Published会正确发送更新通知,视图会响应activeElements的变化完成刷新。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 08:25:21