首页 > 解决方案 > 错误域 = NSPOSIXErrorDomain 代码 = 28 “设备上没有剩余空间” UserInfo = {_kCFStreamErrorCodeKey = 28,_kCFStreamErrorDomainKey = 1}

问题描述

最近从我们的 iOS 设备发出的许多使用 Alamofire 的网络请求失败并出现以下错误:

错误域=NSPOSIXErrorDomain 代码=28“设备上没有剩余空间”UserInfo={_NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask .<3>,_kCFStreamErrorDomainKey=1,_NSURLErrorRelatedURLSessionTaskErrorKey=(“LocalDataTask .<3>”),_kCFStreamErrorCodeKey=28}

如果用户移动了 +- 10 米,我们的应用程序具有发送网络请求的机制。每 5 秒检查一次,因此理论上每 5 秒可以进行一次呼叫。网络请求偶尔会失败并显示此消息,不返回状态代码和上述错误。

该消息暗示错误与设备上的可用磁盘/内存空间有关。但是,在检查两者之后,没有找到链接,因为有足够的可用空间。此外,该错误发生在多台设备上,均运行 iOS 14.4 或更高版本。

是否有关于错误代码 28 的信息以及 iOS 设备上的罪魁祸首是什么?更好;如何防止此错误?

标签: alamofire

解决方案


要回答错误本身的发生:

NSPOSIXErrorDomain Code=28 "设备上没有剩余空间"

在 Xcode 终端中使用日志:

2021-05-07 15:56:50.873428+0200 MYAPP[21757:7406020] [] nw_path_evaluator_create_flow_inner NECP_CLIENT_ACTION_ADD_FLOW 05CD829A-810D-412F-B86E-7524369359E8 [28: 没有剩余空间]

2021-05-07 15:56:50.877243+0200 MYAPP[21757:7400322] 任务 <5504BCDF-7DFE-4045-BD4B-E75054636D5B>.<1> 以错误结束 [28] 错误域 = NSPOSIXErrorDomain 代码 = 28“没有空间留在设备上" UserInfo={_NSURLErrorFailingURLSessionTaskErrorKey=LocalUploadTask <5504BCDF-7DFE-4045-BD4B-E75054636D5B>.<1>, _kCFStreamErrorDomainKey=1, _NSURLErrorRelatedURLSessionTaskErrorKey=( "LocalUploadTask <5504BCDF-7DFE-4045-BD4B-E75054636DB5>.<1> " ), _kCFStreamErrorCodeKey=28}

当创建太多 NSURLSessions 时,它似乎会被调用,达到(在我们的测试中)600-700 个会话的限制,这些会话没有正确维护或关闭。从 iOS 14 开始,该错误开始出现,因此看看是否引入了限制很有趣。

Linked 是一个 github 问题,指出 JetBrains 在 ktor 微服务框架上的相同问题,指向相同的方向,提到会​​话无效以防止此问题: https ://github.com/ktorio/ktor/issues/1341

在我们自己的项目中,问题的根源原来是我们对 StarScream websocket 库的实现。这可能与其他人遇到的问题无关,但无论如何都要解释以创建问题的完整图景。这是我们具体情况的原因和解决方法。

起初,我们认为它与 Alamofire(使用的网络库)创建的 URLSession 有关,因为 POST 请求开始被取消,而杀死应用程序似乎是再次发出请求的唯一解决方案。

然而,我们也使用了使用 StarScream 库的 websocket 连接,它尝试连接到一个套接字,如果失败,则每两秒重试一次连接,最长为两小时。这意味着在两个小时内,每两秒,我们连接到套接字 -> 收到连接失败 -> 断开套接字 -> 再次连接。使用单例的套接字被认为不可能创建多个 URLSession,因为套接字只启动一次。然而,再次调用连接到套接字会创建一个新的 nw_connection 对象,因为库没有正确处理断开连接。

套接字连接中生成的 NWConcrete_nw_connection 对象的图像

验证的方法是使用仪器应用程序检查新 nw_connection 对象的创建。在那里记录为“内存泄漏”,nw_connection 对象的创建被记录下来,解决方案是确保我们在再次连接之前正确断开套接字(使会话无效)。

我希望在这里回答问题的很大一部分,并且我会标记我自己的问题已回答,因为这是手头问题的解决方案。我认为 Apple 应该考虑提供有关有限创建对象数量的准确报告,而不是给出错误“设备上没有剩余空间”。


推荐阅读