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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 17:42:12