6

我一直试图了解 UIWebView 缓存是如何工作的。因为我的目标是能够管理 UIWebView 分配的内存(至少,尽可能多),以避免内存无限增加和应用程序因此而被杀死。

阅读了 其他 stackoverflow 问题搜索 网络之后,我决定尝试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,并将最后一张图片上传到他们的公共提要。每个图像都附加到一个列表中。整个过程每秒重复一次,直到我们从提要中下载 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 :

// 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 来缓存下载的图像。

达到 1000 张图像后的仪器演变

有人知道我在做什么错吗?我误解了什么吗?我加载页面错误吗?UIWebView 是否对 JS 中加载的图像使用另一个缓存?

请让我知道你的想法。我真的需要了解这个 sharedURLCache 是如何工作的,以及 UIWebView 如何使用它来缓存 URLRequest、图像……以防万一它被使用。我不想有一个使用 UIWebView 的应用程序,它可以不受控制地分配内存。

4

1 回答 1

1

你最后是怎么做到的?我注意到您*sharedCache initWithMemoryCapacitydiskPath论点是nil.

来自苹果 doco:

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

查看两位实验室关于如何使用缓存的链接: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];
...

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

响应内存警告

我们在使用 Web 视图的应用程序中看到的最常见崩溃原因是在出现内存警告时没有释放足够的内存而被弹出。当您的应用程序收到内存警告时,您应该清除共享缓存以释放内存. 在您的 UIApplicationDelegate 中执行此操作:

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

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

于 2013-10-17T20:11:22.660 回答