6

UIWebView キャッシュがどのように機能するかを理解しようとしています。私の目標は、UIWebViewによって割り当てられたメモリを(少なくとも、可能な限り)管理できるようにすることであるため、メモリが無期限に増加し、これが原因でアプリが強制終了されるのを回避します。

他のスタックオーバーフローの質問を読んで web検索した後、 NSURLCache sharedURLCacheを試すことにしましたが、それが実際にどのように機能するのかわかりません。

私のテストシナリオは次のとおりです。

内部に UIWebView を持つ単一のビューがあるiOS 5用のテスト アプリを実装しました。この 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ファイルには、Flickr から JSON をダウンロードし、パブリック フィードにアップロードされた最後の画像を含む JS スクリプトがあります。各画像はリストに追加されます。フィードから 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) メモリが増え続けます。この sharedURLCache を使用して、ダウンロードした画像をキャッシュします。

画像1000枚到達後の機器の進化

誰かが私が間違っていることを知っていますか? 私は何か誤解していますか?ページの読み込みが間違っていますか? UIWebView は、JS に読み込まれた画像に別のキャッシュを使用しますか?

あなたの考えを教えてください。この sharedURLCache がどのように機能するか、UIWebView がそれを使用して URLRequest や画像などをキャッシュする方法を理解する必要があります。コントロールなしでメモリを割り当てることができる UIWebView を使用するアプリは必要ありません。

4

1 に答える 1

1

これで結局どうなったの?の引数*sharedCache initWithMemoryCapacityがあることに気付きました。diskPathnil

りんごドコ より:

iOS では、path はアプリケーションのデフォルト キャッシュ ディレクトリのサブディレクトリの名前で、ディスク上のキャッシュが保存されます (サブディレクトリが存在しない場合は作成されます)。

キャッシュの使用方法については、Two Bit Labs による次のリンクを確認してください: 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];
}

これで、プロファイラーでアプリを実行すると、メモリ使用率が横ばいになり、シミュレーターでメモリ警告をトリガーすると、メモリ使用率が低下することがわかります。

于 2013-10-17T20:11:22.660 に答える