4

次のコードは、さまざまなサイズのサーバーから 700 以上の画像をダウンロードします。ここでの問題は、メモリ (ARC を使用しても) が解放されず、最終的にメモリ警告が表示され、その後アプリケーションが終了することです。このメソッドで @autoreleasepool を試しましたが、うまくいかないようです。また、別の場所で for ループを停止して、終了後にメモリが解放されるかどうかを確認しようとしましたが、そうではありません。

このメソッドは for ループ内で呼び出され、画像の URL と短い名前を受け取ります。バックグラウンド スレッドとメイン スレッドで同じ結果が得られました (メモリに関して)。

-(void)saveImage:(NSString*)image name:(NSString*)imageName{     
    int k = 0;
    for (int j = 0; j < [imageName length]; j++) {
        if ([imageName characterAtIndex:j] == '/') {
            k = j;
        }
    }if (k != 0) {
        imageName = [imageName substringFromIndex:k+1];
    }    

    NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@", imageName]]; 

    if ([fileManager fileExistsAtPath:fullPath]) {
        [fileManager removeItemAtPath:fullPath error:nil];
    }

    NSURL *url = [NSURL URLWithString:image];
    NSData *data = [[NSData alloc]initWithContentsOfURL:url];
    NSLog(@"Saved: %d:%@", [fileManager createFileAtPath:fullPath contents:data attributes:nil], url); 
    data = nil;
}  


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

int cacheSizeMemory = 4*1024*1024; // 4MB
int cacheSizeDisk = 32*1024*1024; // 32MB
NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:cacheSizeMemory diskCapacity:cacheSizeDisk diskPath:@"nsurlcache"];
[NSURLCache setSharedURLCache:sharedCache];

self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];
self.window.rootViewController = self.viewController;
[[UIApplication sharedApplication] setStatusBarHidden:YES];
[self.window makeKeyAndVisible];
return YES;
}

- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
NSLog(@"mem warning, clearing cache");
[[NSURLCache sharedURLCache] removeAllCachedResponses];
}

割り当て

4

2 に答える 2

5

スクリーンショットに基づいて、問題は実際の NSData オブジェクトではなく、NSURL キャッシュにあると思います。次のことを試してみてください:

アプリケーション デリゲートで、初期 URL キャッシュをセットアップします。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Do initial setup
    int cacheSizeMemory = 16*1024*1024; // 16MB
    int cacheSizeDisk = 32*1024*1024; // 32MB
    NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:cacheSizeMemory diskCapacity:cacheSizeDisk diskPath:@"nsurlcache"];
    [NSURLCache setSharedURLCache:sharedCache];

    // Finish the rest of your didFinishLaunchingWithOptions and head into the app proper
}

以下をアプリケーション デリゲートに追加します。

- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
    [[NSURLCache sharedURLCache] removeAllCachedResponses];
}

キャッシュ ファイルが作成されます。"Library/Caches/your_app_id/nsurlcache"

Apple の例へのリンクは次のとおりです: URL キャッシュ

コードはテストされていませんが、これ (または同様のもの) は問題を分類する必要があります + さらに、キャッシュサイズを試すことができます。

このコードを使用した割り当ての別のスクリーンショットを投稿できますか? メモリ使用量の増加が止まり、横ばいになることを期待しています。

于 2012-07-06T16:35:59.480 に答える
1

" dataWithContentsOfURL"は自動解放されたNSDataオブジェクトを返しますが、通常は実行ループの終了またはメソッドの終了まで解放されないため、メモリがすぐにいっぱいになるのも不思議ではありません。

明示的な" initWithContentsOfURL"メソッドに変更し、画像データが完全に終了したら、""を実行して強制的にリリースします。data = nil;

于 2012-07-05T19:19:07.287 に答える