NSInvalidArgumentException: *** -[NSConcreteMutableData initWithCapacity:]: 荒谬的容量:3794795864,最大大小:2147483648 字节

NSInvalidArgumentException: *** -[NSConcreteMutableData initWithCapacity:]: absurd capacity: 3794795864, maximum size: 2147483648 bytes

我的 iOS 应用正在下载一个非常大的 zip 文件(3.79GB),使用 AFNetworking. My app also used Flipboard's FLEX 库 2.2 来监控网络流量。一位用户报告说,一旦应用程序触发下载请求,应用程序就会崩溃并显示以下堆栈跟踪:

Crashed Thread

0   CoreFoundation 0x22c6010b __exceptionPreprocess + 124
1   libobjc.A.dylib 0x22406e17 objc_exception_throw + 36
2   CoreFoundation 0x22c60051 +[NSException raise:format:] + 110
3   Foundation 0x233bed7d -[NSConcreteMutableData initWithCapacity:] + 106
4   previewer 0x001e9c3d __86-[FLEXNetworkObserver(NSURLConnectionHelpers) connection:didReceiveResponse:delegate:]_block_invoke (FLEXNetworkObserver.m:946)
5   libdispatch.dylib 0x227d9b5b _dispatch_call_block_and_release + 8
6   libdispatch.dylib 0x227e675b _dispatch_queue_drain$VARIANT$mp + 1756
7   libdispatch.dylib 0x227e5d99 _dispatch_queue_invoke$VARIANT$mp + 282
8   libdispatch.dylib 0x227e8495 _dispatch_root_queue_drain + 394
9   libdispatch.dylib 0x227e8305 _dispatch_worker_thread3 + 94
10  libsystem_pthread.dylib 0x22997b29 _pthread_wqthread + 1022
11  libsystem_pthread.dylib 0x22997718 start_wqthread + 6

崩溃原因:

NSInvalidArgumentException: *** -[NSConcreteMutableData initWithCapacity:]: absurd capacity: 3794795864, maximum size: 2147483648 bytes

它出现在 FLEXNetworkObserver 的以下几行:

if (response.expectedContentLength < 0) {
    dataAccumulator = [[NSMutableData alloc] init];
} else {
    dataAccumulator = [[NSMutableData alloc] initWithCapacity:(NSUInteger)response.expectedContentLength];
}

他正在使用 iPad 3,他说他无法使用较新的 iPad mini 3 重现该问题。请问这是不是由旧 [=] 的 32 位限制引起的33=] 模型(在本例中为 iPad 3)?导致崩溃的原因是什么?

我将禁用 FLEX 网络调试作为解决此问题的方法。

更新

我通过[[FLEXManager sharedManager] setNetworkDebuggingEnabled:NO];禁用FLEX后可以成功下载文件,所以这与AFNetworking完全无关。

My iOS app is downloading a very large zip file

NSMutableData 被预留以保存它的事实表明,这里的计划不是 下载 文件,而是将其视为 数据 将一直保存在 内存中 。这是非常错误的,尤其是。因为如果你的应用程序试图在内存中保存这么大的对象,它很可能会崩溃。真正的 下载 会下载 到磁盘 并且几乎不需要预留内存。