当从服务器下载并保存大量图像时,iOS内存问题(ARC) [英] iOS Memory issue (ARC) when downloading and saving large ammount of images from server

查看:178
本文介绍了当从服务器下载并保存大量图像时,iOS内存问题(ARC)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码从不同大小的服务器下载700多个图像,这里的问题是该内存(即使使用ARC)也不会被释放,最后出现内存警告,随后应用程序退出。我在这个方法中尝试过@autoreleasepool,似乎不起作用。另外我已经尝试在不同的位置停止for循环,看看内存是否在完成后被释放,但不是。



此方法在循环并接收图像的url和短名称。它已经在后台线程和主线程中尝试了相同的结果(内存明智)。

   - (void)saveImage: (NSString *)图像名称:(NSString *)imageName {
int k = 0; (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)应用程序:(UIApplication *)应用程序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:@ViewControllerbundle:nil];
self.window.rootViewController = self.viewController;
[[UIApplication sharedApplication] setStatusBarHidden:YES];
[self.window makeKeyAndVisible];
返回YES;
}

- (void)applicationDidReceiveMemoryWarning:(UIApplication *)应用程序{
NSLog(@mem warning,clearing cache);
[[NSURLCache sharedURLCache] removeAllCachedResponses];
}

解决方案

根据你的屏幕截图,我认为问题是NSURL缓存而不是实际的NSData对象。您可以尝试以下操作:



在您的应用程序委托中,设置初始URL缓存:

 (BOOL)应用程序:(UIApplication *)应用程序didFinishLaunchingWithOptions :( NSDictionary *)launchOptions {
//初始设置
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];

//完成余下的didFinishLaunchingWithOptions并进入应用程序
}

将以下内容添加到您的应用程序代理:

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

将创建一个缓存文件:库/缓存/ your_app_id / nsurlcache



Apple示例的链接在这里: URL Cache



代码未测试,但这或类似的东西)应该排序你的问题+加上你可以尝试缓存大小。



你可以发布另一个分配屏幕截图吗?我希望看到内存使用停止增长并展开。


The following code downloads 700+ images from a server with varying sizes, the issue here is that memory (even with ARC) is never released and eventually a memory warning appears followed by the application exiting. I've tried @autoreleasepool in this method and that didn't seem to work. Also I've tried stopping the for loop at different locations to see if memory is released after it finished, but it isn't.

This method is called inside a for loop and receives the image url and short name. It has been tried in a background thread and main thread with the same results (memory wise).

-(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];
}

解决方案

Based on your screenshot, I think the issue is with the NSURL caching rather than the actual NSData objects. Can you try the following:

In your Application Delegate, setup an initial URL cache:

- (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
}

Add the following to your Application Delegate:

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

A cache file will be created:"Library/Caches/your_app_id/nsurlcache"

The link to the Apple example is here: URL Cache

Code not tested but this (or something similar) should sort your problem + plus you can experiment with the cache sizes.

Can you post another screenshot of Allocations in action with this code? I would expect to see memory use stop growing and flatten out.

这篇关于当从服务器下载并保存大量图像时,iOS内存问题(ARC)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆