【问题标题】:UIWebView is not deallocating memoryUIWebView 没有释放内存
【发布时间】:2016-02-09 10:45:08
【问题描述】:

我在尝试恢复为我的应用程序中的UIWebView 分配的内存时遇到了一些真正的麻烦。我基本上在单独的ViewController 中临时为用户创建和呈现UIWebView,然后删除所有引用并从堆栈中弹出ViewController。尽管做了所有这些,分配的内存永远不会归还,而且我每次都会被额外的 10 Mb 内存卡住,我再次选择 ViewController

让我们看看我是如何管理这个UIWebView 的。

嗯,首先,我的头文件中有一个本地引用,在这里显示

#pragma mark UIWebView Properties
/// WebView for loading URL resources
@property (nonatomic, weak)UIWebView *webView;

请注意,它不是IBOutlet,我正在以下方法中以编程方式创建此UIWebView,在ViewDidAppear 中触发。

-(void)presentYoutubeVideoWithID:(NSString *)videoID {
    /* Setup UIWebView */
    UIWebView *webView = [[UIWebView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
    /* Set Delegate */
    [webView setDelegate:self];
    /* Set local property */
    [self setWebView:webView];
    /* Add view to ViewController */
    [self.view addSubview:webView];
    /* Set constraints */
    // Removed for simplicity 

    /* Set URL */
    NSString *youTubeVideoHTML = @"<!DOCTYPE html> (Removed) </html>";
    NSString *html = [NSString stringWithFormat:youTubeVideoHTML, self.view.frame.size.width, self.view.frame.size.height, videoID];
    [webView loadHTMLString:html baseURL:[[NSBundle mainBundle]resourceURL]];

    /* Setup Notification */
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(handleWhenDoneButtonClick:)
                                                 name:UIWindowDidBecomeHiddenNotification
                                               object:nil];
}

最后,我清理并“弹出”UIViewController

-(void)handleWhenDoneButtonClick:(NSNotification *)notification {
    /* Remove Observer */
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIWindowDidBecomeHiddenNotification object:self.view.window];
    /* Remove UIWebView from hierarchy */
    [self.webView removeFromSuperview];
    /* Remove self from webView delegate */
    [self.webView setDelegate:nil];
    /* Remove reference because I can */
    [self setWebView:nil];
    /* Dismiss ViewController */
    [self dismissViewControllerAnimated:YES completion:nil];
}

对于一个足够简单的场景,似乎没有什么能真正移除 UIWebView 占用的内存。正如您在此处看到的,内存使用量永远不会减少:

加载 UIWebView 之前:

一旦 UIWebView 打开:

弹出 ViewController 并删除对 UIWebView 的引用后:

据我所知,这里使用的内存量会无限期地持续存在。五分钟后,它仍将分配 34+ Mb。如果我再次打开ViewController,它将分配更多,并且一旦我再次弹出,我将最终获得大约 40 Mb 的“基本”使用量。

泄露: 没有完全被劝阻,我最初去寻找漏洞,以为我在某个地方犯了一些错误。然而,虽然我确实发现了一些非常的漏洞,但它们似乎与UIWebView完全相关。

S.O 上的其他案例: 我在网上寻找解决方案已经有一段时间了,但我发现的唯一真正相关的线程是去年的一个,如下所示:UIWebView taking lots of memory

目前还没有答案,这可能是因为(与大多数其他与该主题相关的问题一样),许多回复提供了通用/相互冲突的建议。比如建议你使用 ARC(谁不使用?),或者告诉 OP 他们不应该保留强引用(即使他们不是,并且代码证明了这一点)。最后,一些答案只是声称内存管理一开始就不是问题,因为有足够的东西可以解决,这些也不是有用的答案。

无论如何,这是我目前面临的问题。感谢您花时间阅读本文(如果您这样做了!)。

【问题讨论】:

    标签: ios objective-c xcode uiwebview automatic-ref-counting


    【解决方案1】:

    我也遇到过同样的问题。在 iOS 9 设备中推送 UIViewControllerUIWebView(加载 google.com)时,内存大小从 26 MB 变为 36 MB,并且在弹出控制器后保持不变。

    我使用WKWebView (iOS 8+) 而不是UIWebView 进行了相同的测试。这一次,内存大小从 26 MB 变为 ~27.5 MB,并在弹出控制器后回落至 ~26 MB。

    看来问题的部分原因在于UIWebView 的实现方式。也许你可以使用https://github.com/floatlearning/FLWebView,这是一个WKWebViewUIWebView iOS 的后备。

    【讨论】:

    • 最终切换到 WKWebView,因为它只使用了大约 5-6 MB 而不是 30。但是,这并没有真正解决我的 UIWebView 问题。但显然没有人能真正做到这一点,因为它“打算”以这种方式运作。
    猜你喜欢
    • 2014-11-17
    • 2018-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多