我遇到了内存泄漏,但无法通过泄漏、构建/分析或整体检查来找出如何修复。我有一个非常强烈的想法,这是由于我的 UIWebview 加载 JavaScript 的 loadRequest 命令造成的,但我不知道出了什么问题。
这是我的设置:
我有一个 tabbarcontroller,我以编程方式创建了 4 个 View Controller :分别是一个 TableView 、一个 map View 、另一个 TableView 和一个 Web View 。
- 第一个表格 View 显示静态数据。
- map View 显示注释,单击该注释会填充第四个选项卡(即 Web View )的变量,并切换到 Web View 以显示本地存储的 html/javascript 文件(即 3D 模型)
- 第二个表格 View 以表格形式列出了 map View 中每个注释所代表的所有相同信息。它在填充变量、在 web View 中切换和显示 html/javascript 文件方面具有相同的功能
- webview 显示加载的 html/javascript 文件,如果没有,则显示 UIAlertView 以从 map View 或列表中选择一个
当我最终从 WebView 执行 loadRequest() 时,最初一切正常。但是,当我开始在选项卡之间切换并查看不同的 3D 模型时(即,转到 map View ,单击注释以显示模型 x,观看它在 Web View 中加载,然后切换到列表并单击一行以显示模型) y(或 x )并观察它在 web View 中加载)我开始在 ipad 上收到内存泄漏,而不是模拟器。这些内存泄漏几乎总是:常规 block 56、1024、8、244 和 24,并且没有负责的帧、库或堆栈跟踪可供跟踪。
在webview中,如果我注释掉loadrequest行或使用请求对象= nil执行loadrequest,我没有内存泄漏,但是当我切换到使用指向本地文件的url对象时(我什至尝试指向它到 google.com,其中有 javascript)它会引发内存泄漏。
我尝试过执行以下每一项操作:
- [self.webView loadRequest:nil];
- [self.webView loadHTMLString:@""baseURL:nil];
- [self.webView停止加载];
在我的 webViewController 的 viewWillDisappear 中,试图完全清除 webview 以供将来重用,但它似乎没有多大帮助。我也尝试在执行 loadRequest 之前执行此操作,但我遇到了相同的内存泄漏。
- 仅供引用,我正在运行最新的 xcode 4.0.2,ipad 具有最新更新 4.3.2
- 从我之前评论过但没有收到回复(general-block memory leak)我相信问题与以下事实有关:当我切换 View 时,webview 不知道如何完全摆脱 JavaScript
- 我用一个没有 JavaScript 的简单 html 文件进行了测试,一般 block 内存泄漏消失了。但是,我收到其他 cfnetwork/http 消息内存泄漏,但这是一个不同的故事,目前不是我关心的问题。
下面是单击 mapView 上的注释之一时触发 webViewController 中的 loadModel 函数的示例代码:
- (void) mapCallOutPressed: (UIView *) sender {
NSInteger selectedIndex = sender.tag;
MyLocation *selectedObject = [_mapView.annotations objectAtIndex:selectedIndex];
MyModel *model = selectedObject.model;
NSLog(@"Model selected from mapview = %@", model.description);
// Get reference to the webview from the tabBarController (viewController's index=3)
WebViewController *webViewController = [self.tabBarController.viewControllers objectAtIndex:3];
webViewController.model = model;
[webViewController loadModel];
// Switch tabs to the webView
self.tabBarController.selectedIndex = 3;
[self.tabBarController.selectedViewController viewDidAppear:YES];
下面是我的 webViewController.h 和 .m:
WebViewController.h:
WebViewController : UIViewController <UIWebViewDelegate> {
UIWebView *webView;
NSString *templateRunFilePath;
MyModel *model;
NSString *templateRunTitle;
@property (nonatomic, retain) UIWebView *webView;
@property (assign) MyModel *model;
@property (nonatomic, copy) NSString *templateRunFilePath;
@property (nonatomic, copy) NSString *templateRunTitle;
-(void) loadModel;
WebViewController.m:
- (void) viewDidLoad {
[super viewDidLoad];
NSLog(@"in webview did load");
self.webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height)];
self.webView.delegate = self;
self.webView.autoresizingMask=(UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth);
self.webView.scalesPageToFit = YES;
[self.view addSubview:self.webView];
}
- (void) viewWillAppear:(BOOL)animated {
if (self.model) {
self.tabBarController.navigationItem.title = [NSString stringWithFormat: @"%@ - %@", self.tabBarController.navigationItem.title, self.model.description];
}
else {
UIAlertView *msg = [[UIAlertView alloc] initWithTitle:@"No Model Selected"
message:@"Please select a model from the map or list tab to view."
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[msg show];
[msg release];
}
}
- (void) loadModel {
NSString *localURLPath = [NSString stringWithFormat:@"%@/%@/%@", self.templateRunFilePath, self.model.folderName, self.model.modelFileName];
NSURL *url = [NSURL fileURLWithPath:localURLPath];
NSURLRequest *requestObj = [NSURLRequest requestWithURL: url];
[self.webView loadRequest:requestObj];
}
- (void)webViewDidFinishLoad:(UIWebView *)webView {
[[NSUserDefaults standardUserDefaults] setInteger:0 forKey:@"WebKitCacheModelPreferenceKey"];
}
-(void)viewWillDisappear:(BOOL)animated {
NSLog(@"webview view will disappear");
[super viewWillDisappear:animated];
//[self.webView loadRequest:nil];
//[self.webView loadHTMLString:@"" baseURL:nil];
self.webView.delegate = nil;
}
- (void)dealloc {
self.webView.delegate = nil;
[self.webView release];
[super dealloc];
}
如果您有任何建议或更正,我将不胜感激。我有 <1 周的时间来解决这个问题,如果您能给我任何见解,我将非常感谢。
谢谢!
-迈克
最佳答案
迈克,我不确定你是有意还是无意地关注了?
- (void) loadModel {
[self.webView loadHTMLString:@"" baseURL:nil]; // here you are loading... or you have tried with commenting it also?
NSString *localURLPath = [NSString stringWithFormat:@"%@/%@/%@", self.templateRunFilePath, self.model.folderName, self.model.modelFileName];
NSURL *url = [NSURL fileURLWithPath:localURLPath];
NSURLRequest *requestObj = [NSURLRequest requestWithURL: url];
[self.webView loadRequest:requestObj]; // again here you are also loading?
}
关于iphone - 使用 UIWebView loadRequest 的常规 block 56、1024、8、244、24 内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5739696/