防止UIWebView无限期地分配内存(NSURLCache显然不工作)

问题描述:

我一直在试图了解UIWebView缓存如何工作。由于我的目标是能够管理由UIWebView(至少尽可能)分配的内存,以避免无限期地增加内存并导致应用程序因此而死亡。防止UIWebView无限期地分配内存(NSURLCache显然不工作)

readingother*questionssearchingtheweb后,我决定尝试NSURLCache sharedURLCache,但我无法弄清楚它是如何真正起作用。

我的测试场景是这样:

我实现了一个测试程序为的iOS 5在那里我有一个内部的一个UIWebView的单一视图。这UIWebView的是要加载本地的index.html文件像这样:

// Create an NSString from the local HTML file 
NSString *fullURL = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html" inDirectory:@"www"]; 
NSURL *url = [NSURL fileURLWithPath:fullURL]; 
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url]; 
// Load local HTML file 
[self.webView loadRequest:requestObj]; 

在这种的index.html文件,我有一个JS脚本,下载来自Flickr与上传到最后图像的JSON他们的公共饲料。每个图像都附加到列表中。整个过程每秒重复一次,直到我们从Feed中下载1000个图像。看到代码:

var nImg = 0; 

function getData() 
{ 
    $.getJSON('http://api.flickr.com/services/feeds/photos_public.gne?format=json&jsoncallback=?', function(data) 
    { 
     var items = []; 
     $.each(data.items, function(i, image) { 
      items.push('<li id="' + image.title + '"><img src="' + image.media.m + '"/></li>'); 
     }); 
     $('#page > #imagesList').append(items.join'')); 
     nImg += items.length; 
    }); 
    $('#page > #numImages').html(nImg); 

    if(nImg < 1000) 
     setTimeout("getData();", 1000); // Get more data in 1s 
} 

$(document).ready(function() 
{ 
    getData(); 
}); 

最后,在我的AppDelegate,我成立了sharedURLCache写在这个post

// Initialize the Cache, so we can control the amount of memory it utilizes 
int cacheSizeMemory = 4*1024*1024; // 4MB 
int cacheSizeDisk = 32*1024*1024; // 32MB 
NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:cacheSizeMemory diskCapacity:cacheSizeDisk diskPath:nil]; 

[NSURLCache setSharedURLCache:sharedCache]; 

但是,尽管它是应该发生的,当我打开仪器和运行应用程序检查分配,内存不断增长,而我们下载图像(高达20MB),而不是像我所期望的那样展平4-6MB左右,如果UIWebView将使用此sharedURLCache来缓存下载的图像。

Instruments evolution after we reach 1000 images

有谁知道我在做什么错?我误解了一些东西吗?我是否加载页面错误? UIWebView是否使用另一个缓存来处理JS中加载的图像?

请让我知道你的想法。我真的需要了解这个sharedURLCache是​​如何工作的,以及UIWebView如何使用它来缓存URLRequest,图像......以防万一它被使用。 我不想拥有一个使用UIWebView的应用程序,该应用程序可以在无需控制的情况下分配内存。

你到底是怎么回事? 我注意到你的*sharedCache initWithMemoryCapacity有一个diskPath参数是nil

从苹果DOCO:

在iOS中,路径是应用程序的 默认缓存目录的子目录,在其中存储在磁盘上的高速缓存的名称(如果它创建 子目录不存在)。

结帐这个链接就如何使用缓存两位实验室: http://twobitlabs.com/2012/01/ios-ipad-iphone-nsurlcache-uiwebview-memory-utilization/

配置共享缓存

首先,让我们配置的缓存时,应用程序启动(任何请求之前,所以我们可以控制它使用的内存量。在你的UIApplicationDelegate中:

- (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"] autorelease]; 
    [NSURLCache setSharedURLCache:sharedCache]; 
... 

上面配置了一个带有32MB磁盘缓存的4MB内存缓存。磁盘缓存将驻留在名为“nsurlcache”的子目录中的默认iOS缓存目录中。

回应内存警告

我们的应用程序已经看到了崩溃使用Web视图的最常见的原因被驱逐出场时内存警告进来,当你的应用程序接收存储器没有腾出足够的内存警告,您应该清除共享缓存以释放内存。在UIApplicationDelegate做到这一点:当您运行的探查您的应用程序

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

现在,你应该看到内存使用率变平了,如果你在模拟器触发内存警告你应该看到的内存使用量下降。

+0

感谢您的回答! 我没有弄清楚问题是什么,你引用的链接和我实际上遵循的是同一个测试(你可以看到我把它链接到我的问题中):$ – veducm 2013-10-17 20:59:33