SwiftUI @Environment(\.refresh) 在iOS 17.1+版本中失效问题问询
iOS 17.1+ 中使用
refreshable 修饰符结合 @Environment(\.refresh) 导致应用挂起的问题及解决方案 按照官方文档使用refreshable修饰符时,该功能在iOS 16.4和iOS 17.0.1中可正常工作,但在iOS 17.1及iOS 17.2 beta 3版本中失效,调用await refresh?()会直接导致应用挂起。
原问题代码示例:
struct ContentView: View { var body: some View { RefreshableView() .refreshable { print("Refresh finished!") } } } struct RefreshableView: View { @Environment(\.refresh) private var refresh var body: some View { Button("Refresh") { print("Refresh started") Task { await refresh?() } } .disabled(refresh == nil) } }
目前已有不少开发者反馈遇到相同问题,这是iOS 17.1及后续版本中SwiftUI对refresh环境变量的处理存在的已知异常,疑似存在死锁或资源阻塞情况。
可行解决方案
推荐方案:通过参数传递刷新闭包
放弃依赖@Environment(\.refresh),直接将刷新逻辑以异步闭包的形式传递给子视图,彻底规避环境变量带来的异常:struct ContentView: View { var body: some View { RefreshableView(onRefresh: { print("Refresh finished!") }) } } struct RefreshableView: View { let onRefresh: () async -> Void var body: some View { Button("Refresh") { print("Refresh started") Task { await onRefresh() } } } }临时规避:确保刷新闭包无阻塞操作
如果必须使用环境变量,需确保refreshable中的闭包没有同步阻塞代码,同时可添加超时处理提升稳定性(但该方式仍存在风险):// 在refreshable闭包中添加超时控制示例 .refreshable { do { try await Task.sleep(nanoseconds: 5_000_000_000) print("Refresh finished!") } catch { print("Refresh timed out") } }
内容的提问来源于stack exchange,提问作者Kevin Motschmann
相关产品推荐
相关产品推荐

