2012-05-01 15 views
3

250MB未満でファイルをダウンロードするのに問題はありませんが、250MB以上のファイルをダウンロードしようとするとエラーが発生して予告なしにクラッシュします。時にはそれが通過する、時にはそれはしません。漏れが膨らんだり、記憶が失われたりすることはありません。AFNetworkingがクラッシュして大きなファイルをダウンロードする200MB +

また、xcodeでデバッグしているときにクラッシュが発生したことに気付きました。私は、アプリケーションを実行し、大きなファイルをダウンロードするときにデバッグなしで問題がない場合

大きなファイルをダウンロードするときにAFNetworkingクラスに違ったアプローチが必要ですか?

は、ここではそれが特に何かに所有されているoperationように見えない私のコード

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 
+0

小さなパッケージにデータをチャンクし、この大きなファイルをセグメント単位でダウンロードすることについて考えましたか? – CodaFi

+0

"アプリがエラーなしで予告なしにクラッシュする" - そこにエラーがあると思います。デバイスのコンソールを見てみると、あまりにも多くのメモリを使用しているために殺されている可能性があり、最初にメモリの警告を受け取った可能性があります。楽器を使用して、何がメモリを使用しているかを調べてみてください。 – JosephH

+0

xCodeオーガナイザに移動し、デバイスを探します。あなたのアプリクラッシュログを探します。クラッシュログで質問を更新してください。メモリ不足イベントはありますか? –

答えて

2

これはデバッグモードでのみ起こっているようです。デバッグモードがなくなったり、リリース時にこの問題がさらに解決されました。

+0

ありがとうございます。私はそれぞれ約20MBのファイル約30をダウンロードしていました。インストゥルメントをデバッグしたり実行したりするとき、メモリをほとんど使用しないとアプリがクラッシュします。私はこれを数日中働かそうとしています。なぜなら、それはあなた自身の質問に対する解決策だからです。 –

+0

私のアプリはデバッグで60から200ヶ月を使っていました。リリースを切って約40分で安定させました。私は半分の髪を失ってしまいましたが、残りの半分は多くの方に感謝しています! – Antzi

+0

ダウンロードマネージャ(https://github.com/robertmryan/download-manager)を使用して230MBをダウンロードした後、メモリ警告を受け取りました。ファイルサイズは約250MBです。私を助けてください – Apple

1

あるので、それがメモリに固執するという保証はありません。 NSOperationQueue(たぶんAFHTTPClientに添付されているコード)を使って試してみるか、またはこれをアップロードを開始するコントローラーの保持されたプロパティとして設定してください。

+0

良いアイデアは、残念ながら残っていませんでした。不思議なことに、クラッシュはデバッグでのみ発生します。 – yeahdixon

+0

クラッシュログのスタックトレースの6行目が記号化されていないのは残念です。クラッシュはコントローラが「NSNotification」のオブザーバとして追加されたものの、それを受け取るメモリの周りには存在しないようなものによって引き起こされたようです。 – mattt

1

この問題は古いですが、問題はまだ関連しているようですので、私は解決策を投稿します。

約250MBのダウンロード後にクラッシュする同じ問題があり、数バイトがダウンロードされる度にダウンロード進捗ブロックが呼び出されたことが原因であることが判明しました。 。毎秒何度も。だからデリゲートメソッド(おそらくいくつかのことをする)がここから呼び出されると、それはかなりメモリ集中的になることがあります。

私のソリューションは、ダウンロードの進行状況を追跡し、変更が有意である場合のみ、デリゲートメソッドを呼び出すことだった(私が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に減少しました。私。ダウンロードプロセス中に目立ったメモリの上昇はありませんでした(メモリではなくファイルに直接ダウンロードしていると仮定して)。

関連する問題