经过数天将我的头撞在墙上并度过了不眠之夜后,我希望在这里找到一些帮助。我在这里浏览了各种帖子,但是似乎没有答案可以为我提供解决方案。
简而言之,我的问题是我的应用在UIWebView的大量使用(> 10分钟)后崩溃(例如,依次打开较大的新闻纸网站-一个接一个)。
详细说明:
我正在编写一个iPhone应用程序,并从MainViewController推送了一个NavigationController上的browserViewController。 browserViewController加载一个包含UWebView的 Nib (我不以编程方式创建WebView)。 UIWebView使用Interface Builder进行了连接。
当回到Main,然后再回到browserViewController时,如果它为nil,我只会重新创建browserViewController。 (我想保留在UIWebView中加载的内容-仅在出现内存警告时应卸载此 View 并释放所有已使用的内存)。
在MainViewController和browserViewController中,我都响应内存警告,但这似乎不能提供足够的缓解。
在查看Instruments时,我注意到例如CFData(store)不断增加。即使我模拟了内存警告(请参见下面的代码)并在browserViewController上调用viewDidUnload,CFData仍会分配并且不会被释放。
所以我最大的问题是:
如何释放通过“浏览”创建的内存?
这有两种情况:
-如何确保viewDidUnload正确释放分配给CFData(store)的内存?
-当用户继续在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
我尝试了其他职位的各种建议。例如:
NSString *html = @"<html><head></head><body></body></html>";
[browserWebView loadHTMLString:html baseURL:nil];
[[NSURLCache sharedURLCache] removeAllCachedResponses];
NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:0 diskCapacity:0 diskPath:nil];
[NSURLCache setSharedURLCache:sharedCache];
[sharedCache release];
不幸的是,这些都没有帮助“清除缓存”或释放CFData(store)分配的内存。
如果有人能对此有所启发,让我知道我的缺失或做错了,我将不胜感激。
。
。
编辑:
在收到KiwiBastard的初步答复后,我添加了一个屏幕截图,显示了我在Instruments中观察到的内容:
。
。
,从2010年6月开始编辑:
我仍然无法解决这个问题。
在第二次尝试中,我完全以编程方式创建了UIWebView。
还是同样的问题。但是我注意到一个奇怪的行为。例如,如果我将PDF文档加载到webView中,而没有向上或向下滚动PDF页面,则webView&数据将成功发布。但是,一旦我滚动到第二页,该dealloc将不再起作用,并且我的App有时会耗尽内存。这完全是奇怪的,我无法解决。
有人知道吗?帮助?
最佳答案
要释放 CFData ,只需要调用 CFRelease(您的CFData对象名称)即可。