几天后,我的头撞在墙上,睡不着觉,我希望能在这里找到一些帮助。我在这里看过很多帖子,但似乎没有任何一个答案能为我提供解决方案。
简而言之,我的问题是,我的应用程序在大量使用UIWebView (>10分钟)后崩溃(例如,一个接一个地打开更大的新闻报纸站点)。
为了提供更多细节:我正在编写一个iPhone应用程序,而在MainViewController上,我在navigationController上推一个browserViewController。browserViewController加载一个包含UWebView的nib (我不通过编程创建WebView )。UIWebView是使用接口生成器连接起来的。
当返回Main,然后再返回到browserViewController时,我只在browserViewController为零的情况下重新创建它。(我希望将加载的内容保留为UIWebView --只有当存在内存警告时,应该卸载此视图并释放所使用的所有内存)。
在这两种情况下,MainViewController和browserViewController都响应内存警告,但这似乎没有提供足够的缓解。
看一看仪器,我注意到,例如,CFData(商店)一直在增长。即使我模拟一个内存警告(请参阅下面的代码)并在browserViewController上调用browserViewController,CFData仍然是分配的,并且没有被释放。
所以我最大的问题是:
如何释放从“浏览”中创建的内存?
这包括两个案件:
-如何确保viewDidUnload适当地释放分配给我的CFData(存储)的内存?
-当用户一直在browserViewController中加载页面时如何释放内存?
。
谁管理CFData?
有关我的简化示例代码,请参见下面的代码:
MainViewController.h
// MainViewController.h
#import "myAppDelegate.h"
#import "BrowserViewController.h"
@interface MainViewController : UIViewController {
BrowserViewController *browViewController;
}
- (void) switchToBrowserViewController;
@endMainViewController.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];
}
@endBrowserViewController.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;
@endBrowserViewController.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我曾尝试过其他职位的各种建议。例如:
不幸的是,所有这些都无助于“清除缓存”或释放由CFData(存储)分配的内存。
如果有人能给我一些启示,让我知道我错过了什么或者做错了什么,我会非常感激的。
。
。
编辑:
在KiwiBastard的最初回复之后,我添加了一个屏幕截图,显示了我在“仪器”中观察到的情况:

。
。
2010年6月编辑:
我还没能解决这个问题。
在第二次尝试中,我完全以编程的方式创建了UIWebView。
还是一样的问题。然而,我注意到了一种奇怪的行为。例如,如果我将一个PDF文档加载到webView中,并且不上下滚动PDF页面,则webView & data将被成功释放。然而,一旦我滚动到第二页,dealloc就不能再工作了,我的应用程序在某个时候会耗尽内存。这是完全奇怪的,我无法解决这个问题。
有人知道吗?帮助?
发布于 2011-07-25 12:11:26
要发布CFRelease(your CFData ,只需调用CFData object name).即可。
发布于 2010-10-20 23:16:48
我认为可能发生的情况是,您的浏览器从未被释放,而且viewDidUnload可能从未被调用过。
因为您的MainViewController有一个从未发布过的BrowserViewController类型的变量,所以它将驻留在应用程序的生命周期中。另外,由于您只是在切换视图,视图也将保留在内存中。
我可以建议您在需要时尝试创建BrowserViewController变量,并在导航控制器按下之后释放它吗?
BrowserViewController *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];
[browViewController release];我知道它会轻微地影响性能,因为它每次都要加载nib,但是您显然不想缓存vc?
发布于 2012-02-18 05:24:29
在我读过的某个地方,这是一个众所周知的UIWebView bug。有人说要使用静态的webview对象来避免一次又一次地初始化它,但是找不到合适的解决方案。即使你也遵循同样的方法。幸运的是,我的需求是一个带有图像的普通web视图。因此,我最终使用了一个带有UIImageView和UITextView的自定义控制器,而无需编辑。对我来说很好。
https://stackoverflow.com/questions/3982955
复制相似问题