简而言之,我的问题是,我的应用程序在UIWebView的大量使用(> 10分钟)后崩溃(例如,一个接一个地打开较大的新闻纸站点).
给更多的细节:
我正在编写一个iPhone应用程序,并从MainViewController中,在navigationController上拖动一个browserViewController. browserViewController加载一个包含UWebView的笔尖(我不编程地创建WebView). UIWebView使用Interface Builder进行连接.
当返回到Main然后再次浏览browserViewController时,我只重新创建browserViewController,如果它为零. (我想保留加载的UIWebView的内容 – 只有有一个内存警告,这个视图被卸载并释放所有使用的内存).
在两者中,MainViewController和browserViewController都响应了内存警告,但这似乎没有提供足够的缓解.
看着仪器我注意到,例如CFData(存储)不断增加.即使我模拟内存警告(参见下面的代码)并在browserViewController上调用viewDidUnload,CFData仍然被分配并且不会被释放.
所以我最大的问题是:
如何释放从“浏览”创建的内存?
这涉及两种情况:
– 如何确保viewDidUnload正确释放分配了我的CFData(存储)的内存?
– 当用户在browserViewController中加载页面时如何释放内存?
.
谁管理CFData?
请参阅下面的简化示例代码:
MainViewController.h
// MainViewController.h #import "myAppDelegate.h" #import "BrowserViewController.h" @interface MainViewController : UIViewController { BrowserViewController *browViewController; } - (void) switchToBrowserViewController; @end
MainViewController.m
// MainViewController.m #import "MainViewController.h" @implementation MainViewController - (void)didReceiveMemoryWarning { // Releases the view if it doesn't have a superview. [super didReceiveMemoryWarning]; [browViewController release]; browViewController = nil; } - (void)viewDidUnload { // Release any retained subviews of the main view. // e.g. self.myOutlet = nil; } - (void)dealloc { [browViewController release]; browViewController = nil; [super dealloc]; } - (void) switchToBrowserViewController { // create new browViewController if needed if ( browViewController == nil ) { browViewController = [[BrowserViewController alloc] initWithNibName:@"BrowserViewController" bundle:nil]; } browViewController.navigationItem.hidesBackButton = YES; [((myAppDelegate *)[UIApplication sharedApplication].delegate).navController setNavigationBarHidden:YES animated:NO]; [UIView beginAnimations:nil context:NULL]; [UIView setAnimationDuration: 1]; [UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView: ((myAppAppDelegate *)[UIApplication sharedApplication].delegate).navController.view cache:YES]; [((myAppAppDelegate *)[UIApplication sharedApplication].delegate).navController pushViewController:browViewController animated:NO]; [UIView commitAnimations]; } @end
BrowserViewController.h
// BrowserViewController.h #import <UIKit/UIKit.h> #import "myAppDelegate.h" @interface BrowserViewController : UIViewController <UIWebViewDelegate> { IBOutlet UITextField *browserURLField; IBOutlet UIWebView *browserWebView; } @property (nonatomic,retain) UIWebView *browserWebView; - (void) loadURLinBrowser; @end
BrowserViewController.m
// BrowserViewController.m #import "BrowserViewController.h" @implementation BrowserViewController @synthesize browserWebView; - (void)viewDidLoad { [browserWebView setDelegate:self]; [super viewDidLoad]; } - (void)didReceiveMemoryWarning { // Releases the view if it doesn't have a superview. [super didReceiveMemoryWarning]; } - (void)viewDidUnload { [super viewDidUnload]; [browserWebView stopLoading]; [browserWebView setDelegate:nil]; [browserWebView removeFromSuperview]; [browserWebView release]; browserWebView = nil; browserURLField = nil; } - (void)dealloc { [browserURLField release]; browserWebView.delegate = nil; [browserWebView stopLoading]; browserWebView = nil; [browserWebView release]; [super dealloc]; } - (void) switchBackToMainViewController { [((myAppDelegate *)[UIApplication sharedApplication].delegate).navController setNavigationBarHidden:NO animated:NO]; [UIView beginAnimations:nil context:NULL]; [UIView setAnimationDuration: 1]; [UIView setAnimationTransition:UIViewAnimationTransitionCurlDown forView:((myAppAppDelegate *)[UIApplication sharedApplication].delegate).navController.view cache:YES]; [((myAppAppDelegate *)[UIApplication sharedApplication].delegate).navController popViewControllerAnimated:NO]; [UIView commitAnimations]; } - (void) loadURLinBrowser { NSURL *url = [[NSURL alloc] initWithString:browserURLField.text]; NSMutableURLRequest *request = [[NSURLRequest alloc] initWithURL: url]; [browserWebView loadRequest: request]; [request release]; [url release]; } @end
我已经尝试过其他职位的各种建议.例如:
> 1)将一个空页加载到WebView中.
NSString *html = @"<html><head></head><body></body></html>"; [browserWebView loadHTMLString:html baseURL:nil];
> 2)在上述代码中的各个地方使用removeAllCachedResponses
[[NSURLCache sharedURLCache] removeAllCachedResponses];
> 3)setSharedURLCache也没有提供缓解(我也在AppDelegate applicationDidFinishLaunching中使用了这个).
NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:0 diskCapacity:0 diskPath:nil]; [NSURLCache setSharedURLCache:sharedCache]; [sharedCache release];
不幸的是,这些都没有帮助“清除缓存”或释放CFData(存储)分配的内存.
如果有人可以在这里发光,让我知道我失踪或做错了,我将非常感谢.
.
.
编辑:
在KiwiBastard初步回复之后,我添加了一个屏幕截图,显示了我在“仪器”中所观察到的内容:
.
.
自2010年6月起编辑:
我还没有解决这个问题.
在第二次尝试中,我完全以编程方式创建了UIWebView.
还是一样的问题但是我注意到一个奇怪的行为.如果我将PDF文档加载到webView中,而不是向上或向下滚动PDF页面,则WebView&数据成功发布.然而,只要我滚动到第二个页面,dealloc将不再工作,并且我的应用程序在某些时候终止内存不足.这是完全陌生的,我不能解决这个问题.
任何人有什么想法?帮帮我?