经过多天将我的头撞在墙上并度过了一个不眠之夜,我希望能在这里找到一些帮助.我在这里经历了各种各样的帖子,但没有一个答案似乎为我提供了解决方案.
简而言之,我的问题是我的应用程序在UIWebView大量使用(> 10分钟)后崩溃(例如,逐个打开更大的新闻纸张网站 - 一个接一个).
为了提供更多细节:我正在编写一个iPhone应用程序,并从MainViewController我在navigationController上推送一个browserViewController.browserViewController加载一个包含UWebView的笔尖(我不以编程方式创建WebView).UIWebView使用Interface Builder连接.
当回到Main然后再次访问browserViewController时,我只重新创建了browserViewController(如果它是nil).(我想保留在UIWebView中加载的内容 - 只有在有内存警告时才会卸载此视图并释放所有使用的内存).
在MainViewController和browserViewController中我都在响应内存警告,但这似乎没有提供足够的缓解.
看看仪器,我注意到例如CFData(商店)不断增加.即使我模拟了内存警告(请参阅下面的代码)并在browserViewController上调用viewDidUnload,CFData仍然会被分配并且不会被释放.
所以我最大的问题是:
如何释放"浏览"创建的内存?
这有两种情况:
- 如何确保viewDidUnload正确释放分配了我的CFData(存储)的内存?
- 当用户继续在browserViewController中加载页面时如何释放内存?
.
谁管理CFData?
请参阅下面的简化示例代码:
// MainViewController.h #import "myAppDelegate.h" #import "BrowserViewController.h" @interface MainViewController : UIViewController { BrowserViewController *browViewController; } - (void) switchToBrowserViewController; @end
// 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 #import#import "myAppDelegate.h" @interface BrowserViewController : UIViewController { IBOutlet UITextField *browserURLField; IBOutlet UIWebView *browserWebView; } @property (nonatomic, retain) UIWebView *browserWebView; - (void) loadURLinBrowser; @end
// 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 = @""; [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将不再工作,我的应用程序在某些时候最终会耗尽内存.这很奇怪,我无法解决这个问题.
有人有什么想法?救命?