简而言之,我的问题是,我的应用程序在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将不再工作,并且我的应用程序在某些时候终止内存不足.这是完全陌生的,我不能解决这个问题.
任何人有什么想法?帮帮我?