使用 FirestoreDecoder 解码 Firestore 文档时 UI 冻结

Posted

技术标签:

【中文标题】使用 FirestoreDecoder 解码 Firestore 文档时 UI 冻结【英文标题】:UI freezes when using FirestoreDecoder to decode Firestore documents 【发布时间】:2021-06-17 14:26:21 【问题描述】:

我正在从 Firestore 获取数据,映射文档并使用 FirestoreDecoder 对每个文档进行解码。但是,解码文档会暂时冻结 UI。在后台线程上运行代码没有区别。如何防止 UI 在解码过程中冻结?

    let collection = Firestore.firestore().collection("roll_groups")
    
    collection.addSnapshotListener  (snapshot, error) in
        if let error = error 
            print("Error fetching roll groups: \(error.localizedDescription)")
         else if let snapshot = snapshot 
            DispatchQueue.global(qos: .background).async 
                let rollGroups = snapshot.documents.map  doc -> RollGroup? in
                    do 
                        let rollGroup = try FirestoreDecoder().decode(RollGroup.self, from: doc.data())
                        return rollGroup
                     catch 
                        print("Error decoding roll groups: \(error)")
                        return nil
                    
                
                
                DispatchQueue.main.async 
                    completion(rollGroups)
                
            
        
    

【问题讨论】:

对我来说看起来不错。如果可以的话,我会使用 Instruments 中的 Time Profiler 来查明瓶颈。这可能是完成处理程序本身发生的事情。 @BradleyMackey 谢谢,会的!奇怪的是,如果我完全删除完成处理程序,它仍然会冻结,所以我认为这与此无关:( 如果您删除完成处理程序,则不会进行任何解码但 UI 仍然冻结? 您不需要 DispatchQueue.main.async,而且我在您的代码中看不到任何 UI 调用。在 Firebase 闭包中,网络都是在后台线程上完成的,UI 调用是在主线程上自动完成的,因此它永远不会干扰 UI。由于您使用的是第三方库,因此问题可能就在那里,并且与 Firebase 无关。 我会放弃这个库,因为 IMO 这些第三方依赖项应该用于更大的事情,比如路线图和数据库接口。如果您使用它的唯一原因是抽象 Firestore 时间戳对象的编码/解码,那么我什至不会三思而后行摆脱它。您可以将 Firestore 时间戳转换为可与 Codable 一起使用的内容,例如 unix-timestamp(在 Swift 中为 UInt64)、ISO-8601 日期 (hackingwithswift.com/example-code/language/…) 等。 【参考方案1】:

可能的解决方案

看这段代码似乎一切正常,我只是想确认您的方法的completion 绝对是@escaping: completion() 否则可能会导致此问题

另外,可能值得将实际的 DB 调用 (collection.addSnapshotListener) 包含在

DispatchQueue.global(qos: .background).async

只是看看这是否会有所作为,理论上它不应该,但仍然值得一试

【讨论】:

以上是关于使用 FirestoreDecoder 解码 Firestore 文档时 UI 冻结的主要内容,如果未能解决你的问题,请参考以下文章

技术案例Firefly-RK3399多路视频编解码

C#字节数组的常用解码处理方法

ES9023音频解码芯片原理及应用简介

设置定点数学属性

iOS 7:通过 wi-fi 或对等 wi-fi 使用 Multipeer Connectivity 连接设备

NodeMCU学习笔记--- WI-FI连接使用