I'm having some real trouble trying to recover the memory I've allocated for a UIWebView
within my application. I essentially create and present the UIWebView
temporarily for the user in a separate ViewController
, then remove all references and pop the ViewController
from the stack. Despite doing all of this, the memory allocated is never returned, and I get stuck with an extra 10 Mb of memory each time I segue to that ViewController
again.
Let's see how I'm managing this UIWebView
anyways.
Well, for starters, I've got a local reference to it in my header file, show here
#pragma mark UIWebView Properties
/// WebView for loading URL resources
@property (nonatomic, weak)UIWebView *webView;
Notice that it's not an IBOutlet
, I'm creating this UIWebView
programmatically in the following method, fired in 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];
}
And finally, I clean up and "pop" the 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];
}
For a simple enough scenario, nothing seems to actually remove the memory taken up by the UIWebView. As you can see here, the memory usage never decreases:
Before loading the UIWebView:
After popping the ViewController and removing references to UIWebView:
The amount of memory used here persists indefinitely as far as I can tell. After five minutes, it will still have 34+ Mb allocated. If I open the ViewController
again, it will allocate more, and I will end up with about 40 Mb of "base" usage once I pop again.
Leaks:
Not being completely dissuaded, I initially went off to look for leaks, thinking I had made some mistake somewhere. However, while I did actually find some very small leaks, they were seemingly entirely related to UIWebView
.
Other cases on S.O: I've been looking quite some time for a solution to this on the web, but the only really relevant thread I've found is one from last year as seen here: UIWebView taking lots of memory
It doesn't have an answer yet, and that is probably because (Like most other questions related to this topic), a lot of the replies provide generic/conflicting advice. like suggesting you use ARC (Who doesn't?), or informing OP that they shouldn't keep strong references (Even when they aren't, and the code demonstrates that). Finally, some answers just claim that memory management isn't a problem to begin with because there's enough to go around, and those aren't helpful replies either.
Anyways, this is the current issue I am facing. Thank you for taking the time to read this (If you did!).
I have faced the same issue. When pushing a
UIViewController
with aUIWebView
(loading google.com) in an iOS 9 device, the memory size went from 26 MB to 36 MB and it stayed the same after popping the controller.I did the same test using
WKWebView
(iOS 8+) instead ofUIWebView
. This time, the memory size went from 26 MB to ~27.5 MB and it dropped back to ~26 MB after popping the controller.It seems that the problem is partly due to the way
UIWebView
is implemented. Maybe you could use https://github.com/floatlearning/FLWebView, which is aWKWebView
withUIWebView
fallback for iOS.