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

Swift中如何向DispatchGroup.notify传递用户数据以消除ViewModel状态变量

解决方案

核心思路是调整请求回调的参数定义,把接口返回的用户数据直接通过回调透传,完全不需要额外的存储属性中转。

方案1:基于DispatchGroup的适配实现

let dispatchGroup = DispatchGroup()
// 移除原有的userName存储属性

func fetchData() {
    // 保留你原来的两次enter逻辑,对应动画+接口请求两个异步任务
    dispatchGroup.enter()
    dispatchGroup.enter()
    
    // 仅作为方法内局部变量使用,不会污染ViewModel状态
    var fetchedUser: String?
    resolveDataRequirements { [weak self] result in
        defer { self?.dispatchGroup.leave() }
        switch result {
        case .success(let user):
            fetchedUser = user
        case .failure(let error):
            // 可自行补充错误处理逻辑
            print(error)
        }
    }
    
    dispatchGroup.notify(queue: .main) { [weak self] in
        guard let self = self, let user = fetchedUser else { return }
        self.moveToNextScreen(user: user)
    }
}

// 调整回调的参数,直接向外透传接口请求结果
func resolveDataRequirements(_ completion: @escaping ((Result<String, Error>) -> Void)) {
    api.resolve { result in
        completion(result)
    }
}

// 跳转方法改为直接接收参数
func moveToNextScreen(user: String) {
    // 直接使用传入的user参数执行跳转逻辑
}

func reloadData() {
    resolveDataRequirements { [weak self] result in
        guard case .success(let user) = result else { return }
        self?.moveToNextScreen(user: user)
    }
}

这个方案里fetchedUser是方法级别的局部变量,会被notify的闭包自动捕获,既满足了数据传递需求,也不会在ViewModel中产生多余的存储状态。


方案2:iOS 13+ 适配Swift Concurrency更简洁

如果你的项目最低支持版本到iOS 13 / macOS 10.15,用 async/await 可以完全省略手动管理DispatchGroup的逻辑,代码更易维护:

// 等待动画完成的逻辑封装成异步方法
func waitForAnimation() async throws {
    try await withCheckedThrowingContinuation { continuation in
        // 你的动画完成回调里调用 continuation.resume()
    }
}

func resolveDataRequirements() async throws -> String {
    try await withCheckedThrowingContinuation { continuation in
        api.resolve { result in
            continuation.resume(with: result)
        }
    }
}

func fetchData() async {
    do {
        // 两个任务并行执行,全部完成后才会往下走
        async let animationDone = waitForAnimation()
        async let user = resolveDataRequirements()
        let _ = try await animationDone
        moveToNextScreen(user: try await user)
    } catch {
        // 统一处理错误
    }
}

func reloadData() async {
    do {
        let user = try await resolveDataRequirements()
        moveToNextScreen(user: user)
    } catch {
        // 错误处理
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 22:51:02