阻止UIWebView无限期地分配内存(NSURLCache显然无法正常工作)

时间:2013-03-07 15:28:25

标签: ios memory-management uiwebview instruments nsurlcache

我一直在努力了解UIWebView缓存的工作原理。由于我的目标是能够管理UIWebView分配的内存(至少,尽可能多),以避免无限期地提高内存并且App因此而被杀死。

reading other stackoverflow questionssearching the web之后,我决定尝试 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中,我按照post中的说明设置了sharedURLCache:

// 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的应用程序可以在没有控制权的情况下分配内存。

1 个答案:

答案 0 :(得分:1)

你最近怎么做到这一点? 我注意到您的*sharedCache initWithMemoryCapacity的{​​{1}}参数为diskPath

来自apple doco:

  

在iOS中,path是应用程序子目录的名称   默认缓存目录,用于存储磁盘缓存(   如果子目录不存在,则创建它。)

通过Two Bit Labs查看有关如何使用缓存的链接: http://twobitlabs.com/2012/01/ios-ipad-iphone-nsurlcache-uiwebview-memory-utilization/

配置共享缓存

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

nil

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

回应内存警告

我们在使用Web视图的应用程序中看到的崩溃的最常见原因是在内存警告进入时没有释放足够的内存而被弹出。当您的应用收到内存警告时,您应该清除共享缓存释放记忆。在你的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];
...

现在,当您在分析器中运行应用程序时,您应该看到内存利用率变平,如果在模拟器中触发内存警告,您应该看到内存使用量下降。