UIWebView不使用ARC释放所有活动字节

我目前在使用ARC的iOS 5.1中构build一个导航控制器应用程序。 我经常需要显示网页,我已经做了一个Web浏览器,这只是一个UIWebView与周围的一些自定义内容。 当用户完成查看页面时,他们点击后退button,应释放与自定义Web查看器关联的所有内存。 我的问题是,当后退button被击中时,所有内存都不会被释放。 我已经构build了一个玩具应用程序( 在github上 ),它只是一些button,每个button都有一个第一响应者调用不同的页面。

@implementation ViewController -(IBAction)googlePressed:(id)sender { CustomWebView *customWebView = [[CustomWebView alloc] initWithStringURL:@"http://www.google.com"]; [self.navigationController pushViewController:customWebView animated:NO]; } -(IBAction)ksbwPressed:(id)sender { CustomWebView *customWebView = [[CustomWebView alloc] initWithStringURL:@"http://www.ksbw.com/news/money/Yahoo-laying-off-2-000-workers-in-latest-purge/-/1850/10207484/-/oeyufvz/-/index.html"]; [self.navigationController pushViewController:customWebView animated:NO]; } -(IBAction)feedProxyPressed:(id)sender { CustomWebView *customWebView = [[CustomWebView alloc] initWithStringURL:@"http://feedproxy.google.com/~r/spaceheadlines/~3/kbL0jv9rbsg/15159-dallas-tornadoes-satellite-image.html"]; [self.navigationController pushViewController:customWebView animated:NO]; } -(IBAction)cnnPressed:(id)sender { CustomWebView *customWebView = [[CustomWebView alloc] initWithStringURL:@"http://www.cnn.com/2012/04/04/us/california-shooting/index.html?eref=rss_mostpopular"]; [self.navigationController pushViewController:customWebView animated:NO]; } 

CustomWebView只是一个UIWebView链接到IB到UIWebView属性

 @implementation CustomWebView @synthesize webView, link; - (id)initWithStringURL:(NSString *) stringURL { if (self = [super init]) { link = stringURL; } return self; } - (void)viewDidLoad { [super viewDidLoad]; NSURL *url = [NSURL URLWithString:link]; NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url]; [webView loadRequest:urlRequest]; } - (void)viewDidUnload { [super viewDidUnload]; } 

我的问题是,一旦一切都加载,我把堆基线设置为初始ViewController。 然后,我加载一个页面后,检查堆,然后返回到ViewController并获得以下heapshots:

Heapshots

这表明,在每一系列点击一个button并返回到ViewController之后,即使CustomWebView都应该被释放,堆仍会继续增长。

编辑:

上面介绍的示例项目可以在github上find

我有同样的问题,我发现了这个小小的魔力

 /* There are several theories and rumors about UIWebView memory leaks, and how to properly handle cleaning a UIWebView instance up before deallocation. This method implements several of those recommendations. #1: Various developers believe UIWebView may not properly throw away child objects & views without forcing the UIWebView to load empty content before dealloc. Source: http://stackoverflow.com/questions/648396/does-uiwebview-leak-memory */ [webView loadHTMLString:@"" baseURL:nil]; /* #2: Others claim that UIWebView's will leak if they are loading content during dealloc. Source: http://stackoverflow.com/questions/6124020/uiwebview-leaking */ [webView stopLoading]; /* #3: Apple recommends setting the delegate to nil before deallocation: "Important: Before releasing an instance of UIWebView for which you have set a delegate, you must first set the UIWebView delegate property to nil before disposing of the UIWebView instance. This can be done, for example, in the dealloc method where you dispose of the UIWebView." Source: UIWebViewDelegate class reference */ [webView setDelegate:nil]; /* #4: If you're creating multiple child views for any given view, and you're trying to deallocate an old child, that child is pointed to by the parent view, and won't actually deallocate until that parent view dissapears. This call below ensures that you are not creating many child views that will hang around until the parent view is deallocated. */ [webView removeFromSuperview]; 

我一直在使用ARC一段时间,过去我发现Web视图将保持任何被加载,直到它被告知加载其他东西。 我解决这个问题的方法是在视图中使用javascript调用(或Did)方法如下:

 - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; [self.webView loadHTMLString:@"<html></html>" baseURL:nil]; } 

这为我释放内存。

UIWebView是一个内存猪,并没有很好地释放内存。 我在你的CustomWebView类中放了一个 – (void)dealloc调用,当Backbutton被击中时,它被调用。

你可以尝试[[NSURLCache sharedURLCache] removeAllCachedResponses]或者使用然后释放你自己的NSURLCache副本,但坦率地说,UIWebView 从来没有完全清理自己。

我还没有使用ARC,但看着你的自定义的web视图代码,我认为你创build的webviews仍然活着。

如果你想确保你的webview被正确的杀死,请确保在viewWill / DidDisappear中,调用[webview stopLoading],并且没有webview。

(注意:如果你推着另一个视图,那么webview也会被杀死,所以一定要处理好这些问题)

大多数情况下,我有问题的webViews甚至在popupviewController后,callback一些webView委托方法会崩溃的应用程序。 (我猜ARC防止它崩溃)。

让我知道这是否有帮助。

布伦丹有几点意见:

你还没有发布足够的代码来确定发生的事情。 但为什么不拥有一个单一的UIWebView控制器,而不是创build另一个每个button上按只需传递一个string与相关的URL? 这是一个更好的devise模式,可以保证你永远不会有超过一个。

@interface WebViewViewController : UIViewController<UIWebViewDelegate>

 - (void)viewDidLoad { [super viewDidLoad]; NSString* urlAddress = @"http://www.google.com"; NSURL *url = [NSURL URLWithString:urlAddress]; NSURLRequest *requestObj = [NSURLRequest requestWithURL:url]; self.webView.delegate = self; [self.webView loadRequest:requestObj]; } -(void)viewWillDisappear:(BOOL)animated{ [super viewWillDisappear:animated]; [_webView stopLoading]; [_webView loadHTMLString:@"<html><head></head><body></body></html>" baseURL:nil]; [_webView stopLoading]; [_webView removeFromSuperview]; } - (void)dealloc { [_webView stopLoading]; } - (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error { [_webView stopLoading]; _webView = nil; }