web-dev-qa-db-ja.com

使用後のiOS UIWebViewリソースの解放

アプリのホーム画面(つまり、すべてのユーザーが最初に表示する画面)にはいくつかのセクションがあり、そのほとんどがユーザーが開きたいさまざまなWebビューを含んでいます。そうすることで、メモリ使用量がかろうじて26MBから最大85MBまたはそれ以上に増加します(すべての異なるWebビューを開いた後)。

私たちが見つけた問題は、いったん閉じられると、すべてのWebページのリソースがメモリに保持されているように見えることです(使用されたメモリは、おそらく数MBしか減少しません)。

後で、大量のメモリを必要とする非常に要求の厳しいセクションがあり、Webビューをいくつか閲覧していると完全にアプリケーションがクラッシュするため、Webビューが開いていたリソースを解放したいと思います。前。

インターネットでいくつかのオプションを試してみましたが、今のところどれも機能していません。次のようなもの:

// Try to clean used webview

[self.webView loadHTMLString:@"" baseURL:nil];
[self.webView stopLoading];
self.webView.delegate = nil;
[self.webView removeFromSuperview];
self.webView = nil;

メモリ使用量にほとんど影響を与えていません。ここで見逃しているものはありますか?私はすでに、WebViewを開いたままにするリークがないことを再確認しました。持っている唯一の参照を解放しています(self.webView = nil;

編集:プロジェクトを最初から作成し、クリックするたびに別のWebをロードするWebビューとボタンを追加しました。これにより、メモリ使用量が増加します。また、クリックするとWebViewを破棄するボタンを追加しました。メモリは実質的にリソースを解放しないので、メモリは同じままです。

28
h4lc0n

この質問をしてから数か月が経ちましたが、誰も回避策を知らないようですので、私は自分に答えて、閉鎖と悲しいことに、この同じ問題を抱えている人には悪い知らせを伝えています。

私たちは数日間この問題に対抗しようとしましたが、どうしようもないと私たちに何もする必要がないとほのめかした何人かの人々と話しました(それは私たちがアクセスできないすべてのものを処理する別のプロセスです)。カスタムビューページへのWebViewアクセスを制限します。

たとえば、インターネット上でウェブを開くニュースセクションがありました。最終的に行ったのは、ニュースに関連するタイトル、本文、画像を含むオープンなカスタムメイドのWebページでした(これは、リソースのメモリ使用量に追加されますが、何千もの必要な小さい形式で保持することに成功しました)。危険を冒すために開かれるべきニュース)。私は知っています、理想的ではありません。

それでも解決策、回避策、または同じ問題を抱える将来のユーザーを助けることができるアイデアであるかどうかにかかわらず、私はこの質問に対する建設的な答えをいくつか見てみたいと思います。

17
h4lc0n

jason Bakerのこの記事を読んでください。

http://www.codercowboy.com/code-uiwebview-memory-leak-prevention/

彼はcategoryを作成しました。これは、UIWebViewのメモリフットプリントを節約するのに本当に役立ちました。

カテゴリを追加したら、2行呼び出すだけです

-(void) dealloc
{

    [self.webview cleanForDealloc];
    self.webview = nil;
    [super dealloc];

}
7
2intor
override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    categoryWebView.stopLoading()
    categoryWebView.removeFromSuperview()
    categoryWebView = nil

    URLCache.shared.removeAllCachedResponses()
    URLCache.shared.diskCapacity = 0
    URLCache.shared.memoryCapacity = 0
    if let cookies = HTTPCookieStorage.shared.cookies {
        for cookie in cookies {
            HTTPCookieStorage.shared.deleteCookie(cookie)
        }
    }
}
1
Sachin Kishore