Swift中为Firebase分块发送商品数组的事件添加10秒延迟的实现问询
解决分块发送数组并延迟执行Analytics日志的问题
我明白你的需求:分块处理商品数组,并且在每次调用Analytics.logEvent前等待10秒,同时不能阻塞主线程影响用户体验。下面是具体的实现方案,用异步延迟来替代阻塞式的sleep,同时保证分块逻辑正常运行:
方案一:使用DispatchQueue.asyncAfter实现延迟(推荐)
这种方式不会阻塞主线程,而且能清晰地控制每个分块的延迟执行逻辑。我们可以把分块遍历改成递归调用,确保每个块的日志上报完成后(延迟10秒),再处理下一个块:
func viewItemInList(items: [ProductModel]) { let chunkedArray = items.chunked(into: 4) // 启动分块处理流程 processNextChunk(at: 0, from: chunkedArray) } private func processNextChunk(at index: Int, from chunks: [[ProductModel]]) { guard index < chunks.count else { return } // 所有块处理完毕,退出 let currentChunk = chunks[index] var parameterArray: [[String: Any]] = [] // 构建当前块的参数数组 for (itemIndex, item) in currentChunk.enumerated() { var parameters: [String: Any] = [ AnalyticsParameterItemID: item.sku ?? "", AnalyticsParameterItemName: item.name ?? "", AnalyticsParameterItemBrand: "Skechers", AnalyticsParameterPrice: item.price?.clearPrice() ?? 0.0 ] parameters[AnalyticsParameterIndex] = itemIndex parameterArray.append(parameters) } // 准备最终的日志参数 let logParameters: [String: Any] = [ AnalyticsParameterItems: parameterArray ] // 延迟10秒后执行日志上报 DispatchQueue.main.asyncAfter(deadline: .now() + 10) { [weak self] in Analytics.logEvent(AnalyticsEventViewItemList, parameters: logParameters) // 递归处理下一个块,保证顺序执行 self?.processNextChunk(at: index + 1, from: chunks) } }
代码说明:
- 拆分原循环逻辑为递归函数
processNextChunk,确保分块按顺序处理,不会出现多个日志同时触发的情况。 - 使用
[weak self]避免循环引用,防止内存泄漏。 DispatchQueue.main.asyncAfter会在10秒后异步执行闭包代码,主线程不会被阻塞,用户界面依然可以正常交互。
方案二:使用Timer实现延迟
如果你更习惯用Timer,也可以用这种方式,需要注意及时销毁定时器避免内存浪费:
func viewItemInList(items: [ProductModel]) { let chunkedArray = items.chunked(into: 4) var currentChunkIndex = 0 // 创建定时器,每隔10秒触发一次 Timer.scheduledTimer(withTimeInterval: 10, repeats: true) { [weak self] timer in guard let self = self, currentChunkIndex < chunkedArray.count else { timer.invalidate() // 所有块处理完成,销毁定时器 return } let currentChunk = chunkedArray[currentChunkIndex] var parameterArray: [[String: Any]] = [] // 构建当前块的参数 for (itemIndex, item) in currentChunk.enumerated() { var parameters: [String: Any] = [ AnalyticsParameterItemID: item.sku ?? "", AnalyticsParameterItemName: item.name ?? "", AnalyticsParameterItemBrand: "Skechers", AnalyticsParameterPrice: item.price?.clearPrice() ?? 0.0 ] parameters[AnalyticsParameterIndex] = itemIndex parameterArray.append(parameters) } let logParameters: [String: Any] = [ AnalyticsParameterItems: parameterArray ] // 执行日志上报 Analytics.logEvent(AnalyticsEventViewItemList, parameters: logParameters) currentChunkIndex += 1 } }
代码说明:
- 定时器每隔10秒触发一次,每次处理一个分块。
- 当所有分块处理完成后,调用
timer.invalidate()销毁定时器,避免无效的定时触发。 - 同样用
[weak self]规避循环引用问题。
关键注意点:
- 绝对不要用
sleep(10):它会阻塞主线程,导致界面冻结,完全破坏用户体验。 - 确保你的
chunked自定义方法能正确将数组拆分为大小为4的子数组(最后一个子数组长度可能小于4)。 - 两种方案都保证了分块的顺序执行,每个日志上报间隔严格为10秒。
内容的提问来源于stack exchange,提问作者Batuhan Baran
相关产品推荐
相关产品推荐

