Swift中数组按Timestamp降序排序失效问题求助
问题分析与解决方案
嘿,我一眼就发现问题所在啦!你的列表始终按ts升序显示,核心原因和一个潜在优化点如下:
1. 排序方法没有修改原数组(最直接的问题)
Swift 中的 sorted(by:) 方法不会原地修改原数组,它会返回一个全新的排序后的数组。你现在只是调用了这个方法,但没有把返回的结果赋值回 self.allBlogs,所以原数组根本没发生变化!
修正后的排序方法:
func sortDataset(){ // 把排序后的新数组赋值回原数组,用 > 实现降序(ts值高的在前) self.allBlogs = self.allBlogs.sorted(by: { $0.ts! > $1.ts! }) self.rv.reloadData() }
2. 异步请求的顺序问题(潜在优化)
你在循环中对每个 authorId 发起异步的 getDocuments 请求,每个请求完成后都会调用 sortDataset。这会导致:
- 多次重复排序,浪费性能
- 如果某个请求延迟完成,可能会在已经刷新列表后再次触发排序(虽然最终结果正确,但体验不佳)
用 DispatchGroup 等待所有请求完成后再统一处理:
修改你的数据下载方法,确保所有请求都完成后再排序刷新:
func getBlogsByAuthor(){ self.allBlogs.removeAll() let dispatchGroup = DispatchGroup() // 创建调度组 for authorId in self.authorIds{ dispatchGroup.enter() // 每个请求开始前进入组 db.collection("Blogs").whereField("authorId", isEqualTo: authorId) .getDocuments() { (querySnapshot, err) in defer { dispatchGroup.leave() } // 请求结束后离开组(无论成功失败) if let err = err { print("Error getting documents: \(err)") return } for document in querySnapshot!.documents { // 建议用可选绑定替代强制解包,避免崩溃 guard let ts = document.get("ts") as? Int, let title = document.get("title") as? String, let body = document.get("body") as? String, let authorId = document.get("authorId") as? String, let imageUrl = document.get("imageUrl") as? String else { continue // 跳过数据不完整的文档 } let state = document.get("stateios") as? String ?? "Null" let id = document.documentID let blogObject = BlogObject(title: title, body: body, imageUrl: imageUrl, authorId: authorId, state: state, id: id, ts: ts) self.allBlogs.append(blogObject) } } } // 所有请求完成后,在主线程执行排序和刷新 dispatchGroup.notify(queue: .main) { self.sortDataset() } }
额外小建议:
尽量避免使用强制解包 !,如果 Firestore 中的字段可能不存在或类型不匹配,用 guard let 或可选绑定处理,能有效避免运行时崩溃。
内容的提问来源于stack exchange,提问作者Markus Gerlach
相关产品推荐
相关产品推荐

