AFNetworking崩溃,下载大文件200MB +



下载 250MB 以下的文件我没有问题,但是当我尝试下载 250MB + zip 时,应用程序只是突然崩溃,没有错误。有时它通过,有时它没有。泄漏证实没有腹胀或记忆丧失。

另外,我现在注意到崩溃仅在使用 xcode 进行调试时发生。当我运行应用程序并在没有调试时下载较大的文件时,没有问题

下载较大文件时,我是否需要以不同的方式处理 AFNetworker 类?

这是我的代码

NSURL* url=[BFAppGlobals getServerURL:[M.Properties objectForKey:@"zip_path" ]];
NSMutableURLRequest  *request = [NSMutableURLRequest requestWithURL:url];
[request setTimeoutInterval:3600];

 AFHTTPRequestOperation *operation = [[[AFHTTPRequestOperation alloc]  initWithRequest:request] autorelease];
NSString* writePath=[BFAppGlobals getContentResourcePathForFile:strFile];
[delegate onStartDownload:M];
operation.outputStream = [NSOutputStream outputStreamToFileAtPath:writePath append:YES];
[operation setDownloadProgressBlock:^(NSInteger bytesRead, NSInteger totalBytesRead, NSInteger totalBytesExpectedToRead) {
    int b=totalBytesRead ;
    int total=totalBytesExpectedToRead;
    float perc=(float)b/(float)total;
    M.progress=perc;
    [((NSObject*)delegate) performSelectorOnMainThread:@selector(onDataReceviedFromRequest:) withObject:M   waitUntilDone:YES];
}];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
     NSDictionary* params=[NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:writePath,writeDirectory, M, nil] forKeys:[NSArray arrayWithObjects:@"Path",@"Dir",@"Model", nil]];
    [self performSelectorInBackground:@selector(unzipDownloaded:) withObject:params];

} 
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"fail! %@", [error localizedDescription]);
    [delegate onErrorDownload:M WithError:[error localizedDescription]];
    ActiveModel=nil;
}];
[operation start];

****************************  UPDATE ADDED CRASH LOG ***************************************
    Thread 0 Crashed:
    0   libobjc.A.dylib                 0x37d24fbc objc_msgSend + 16
    1   Foundation                      0x35502508 __57-[NSNotificationCenter addObserver:selector:name:object:]_block_invoke_0 + 12
    2   CoreFoundation                  0x381aa570 ___CFXNotificationPost_block_invoke_0 + 64
    3   CoreFoundation                  0x381360c8 _CFXNotificationPost + 1400
    4   Foundation                      0x354763f4 -[NSNotificationCenter postNotificationName:object:userInfo:] + 60
    5   Foundation                      0x35477c24 -[NSNotificationCenter postNotificationName:object:] + 24
    6   BFiPad                          0x0006d2fc 0x1000 + 443132
    7   CoreFoundation                  0x3813d224 -[NSObject performSelector:withObject:] + 36
    8   Foundation                      0x35517750 __NSThreadPerformPerform + 344
    9   CoreFoundation                  0x381b2afc __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 8
    10  CoreFoundation                  0x381b22c8 __CFRunLoopDoSources0 + 208
    11  CoreFoundation                  0x381b106e __CFRunLoopRun + 646
    12  CoreFoundation                  0x381344d6 CFRunLoopRunSpecific + 294
    13  CoreFoundation                  0x3813439e CFRunLoopRunInMode + 98
    14  GraphicsServices                0x37f0bfc6 GSEventRunModal + 150
    15  UIKit                           0x31cb473c UIApplicationMain + 1084
    16  BFiPad                          0x00003f72 0x1000 + 12146
    17  BFiPad                          0x00003f30 0x1000 + 12080

似乎这只发生在调试模式下。用完调试模式或发布更多可以解决此问题

它看起来不像operation是由任何特定的东西拥有的,所以不能保证它会留在内存中。尝试使用NSOperationQueue(也许是附加到AFHTTPClient的,这将清理大量代码(,或在启动上传的控制器中将其设置为保留属性。

我知道

这个问题很旧,但问题似乎仍然相关,所以我无论如何都会发布我的解决方案。

我遇到了同样的问题,下载大约 250MB 后它会崩溃,并发现这是由于每次下载几个字节时都会调用下载进度块这一事实引起的,这意味着它被称为 A LOT。每秒多次。因此,当从这里调用委托方法(可能做一些事情(时,它可能会变得非常占用内存。

我的解决方案是跟踪下载进度,并且仅在更改显着时才调用委托方法(我决定超过 1%(:

[operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
    float progress = ((float)totalBytesRead) / totalBytesExpectedToRead;
    if ((progress - totalProgress) > 0.01) {
        totalProgress = progress;
        [delegate updateProgress:progress];
    }
}];

float totalProgress是一个实例变量。

此修复将内存使用量从崩溃时的大约 280MB 减少到我的应用程序已经在使用的大约 30MB。 即在下载过程中没有明显的内存增加(假设您直接下载到文件,而不是内存(。

最新更新