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

使用Firestore加载用户数据时出现下载暂停问题求助

解决Firestore数据下载暂停的问题

嘿,这个问题我太熟悉了!你现在的代码逻辑有个关键问题:Firestore的文档读取是异步操作,你的三个loadingFunction会立刻返回,不会等数据下载完成,而你紧接着就调用了performSegue——这就导致视图控制器被销毁,Firestore的下载任务自然就暂停了。

下面给你两种常用的解决方案,按需选择:

方案一:用DispatchGroup等待所有异步任务完成

这种方法兼容所有iOS版本,核心是用DispatchGroup来追踪三个加载任务的完成状态,等全部完成后再执行跳转:

override func viewDidLoad() {
    super.viewDidLoad()
    
    let loadGroup = DispatchGroup()
    
    // 每个加载任务开始前标记进入group
    loadGroup.enter()
    loadingFunction1 {
        // 任务完成后标记离开group
        loadGroup.leave()
    }
    
    loadGroup.enter()
    loadingFunction2 {
        loadGroup.leave()
    }
    
    loadGroup.enter()
    loadingFunction3 {
        loadGroup.leave()
    }
    
    // 当所有任务都离开group后,在主线程执行跳转
    loadGroup.notify(queue: .main) {
        self.performSegue(withIdentifier: "goToNextScreen", sender: nil)
    }
}

// 给加载函数添加完成回调
func loadingFunction1(completion: @escaping () -> Void) {
    let docRef = Firestore.firestore().collection("yourCollection").document("yourDocId")
    docRef.getDocument { snapshot, error in
        if let error = error {
            print("加载数据失败:\(error.localizedDescription)")
            // 即使出错也要调用completion,避免group一直等待
            completion()
            return
        }
        // 解析并存储数据...
        completion()
    }
}

// 同理修改loadingFunction2和loadingFunction3,添加completion回调

方案二:用async/await(iOS 15+ / Swift 5.5+)

如果你的项目支持iOS 15及以上,用async/await会让代码更简洁易读,原生支持并发等待:

override func viewDidLoad() {
    super.viewDidLoad()
    
    // 启动一个异步任务
    Task {
        do {
            // 并发执行三个加载任务
            async let data1 = loadingFunction1()
            async let data2 = loadingFunction2()
            async let data3 = loadingFunction3()
            
            // 等待所有任务完成,获取结果
            let (result1, result2, result3) = try await (data1, data2, data3)
            
            // 这里可以处理获取到的三个结果...
            
            // 回到主线程执行跳转(UI操作必须在主线程)
            DispatchQueue.main.async {
                self.performSegue(withIdentifier: "goToNextScreen", sender: nil)
            }
        } catch {
            print("加载数据出错:\(error.localizedDescription)")
            // 这里可以处理错误,比如显示提示给用户
        }
    }
}

// 将加载函数改为async函数
func loadingFunction1() async throws -> YourDataModel {
    let docRef = Firestore.firestore().collection("yourCollection").document("yourDocId")
    let snapshot = try await docRef.getDocument()
    
    // 解析快照到你的数据模型
    guard let data = snapshot.data(), let model = YourDataModel(dictionary: data) else {
        throw NSError(domain: "DataParsingError", code: 0, userInfo: [NSLocalizedDescriptionKey: "无法解析数据"])
    }
    return model
}

// 同理修改loadingFunction2和loadingFunction3,返回对应的数据模型

额外注意事项

  • 一定要处理Firestore的错误,不管是用回调还是do-catch,避免出现任务卡住或者崩溃的情况
  • 如果你的加载函数用的是addSnapshotListener(实时监听),而不是单次读取getDocument,要确保在跳转前已经设置好监听,并且在合适的时机移除监听(比如在viewWillDisappear里)
  • 可以在Loading视图里加个加载指示器(比如UIActivityIndicatorView),在开始加载时显示,所有任务完成后隐藏,提升用户体验

内容的提问来源于stack exchange,提问作者August W Danowski

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:50:59