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
相关产品推荐
相关产品推荐

