-
Creator 版本: 3.8.8
-
目标平台: IOS
-
重现方式:下载的过程中切后台
-
首个报错:
问题描述
在 iOS 平台的 DownloaderImpl-apple.mm 实现中,Cocos 引擎维护了一个 _taskQueue 来管理下载任务的并发。该队列的机制是:
- 运行中任务 :在队列中以 nil 占位。
- 等待中任务 :在队列中保存 NSURLSessionTask 对象的指针,且初始状态为 suspended ,完全依赖引擎调度逻辑(调用 resume )来启动。
崩溃原因分析
当前代码使用了 [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:…] 。
在应用切换到后台时,iOS 的后台下载机制可能会自动调度并启动那些处于 suspended 状态的任务(即引擎认为还在“等待中”的任务)。这会导致这些任务在引擎不知情的情况下在后台完成下载。
当这些“被系统自动完成”的任务触发 didCompleteWithError 回调时,会发生以下冲突:
- 引用移除 :该任务从 taskDict (持有 DownloadTaskWrapper )中被移除。
- 野指针/状态错误 :引擎的 didCompleteWithError 逻辑会处理队列,清理队首的 nil (运行中任务),然后尝试取出队首的 等待任务 并执行 [task resume] 。
- 崩溃 :如果队首的任务恰好是那个被系统自动完成的任务,引擎实际上是在对一个已经完成(且由于从 taskDict 移除,其关联的 Wrapper 可能已释放)的任务调用 resume ,或者访问了 _taskQueue 中已经失效的裸指针,从而导致崩溃。
解决方案 / Fix
将 NSURLSessionConfiguration 改为 defaultSessionConfiguration 。
defaultSessionConfiguration 不具备后台自动调度的特性,任务的生命周期将严格遵循引擎的 resume 调用。这样可以确保 NSURLSession 的实际状态与引擎 taskQueue 的逻辑状态保持一致,避免了系统静默启动任务导致的生命周期管理混乱。
TIP
还注释了后台下载 断点续传相关的功能 ,想问问大家遇到了相关的问题了吗

