使用 UIWebView loadRequest 的常规块 56、1024、8、244、24 内存泄漏

发布于 2024-11-02 08:22:40 字数 4896 浏览 1 评论 0原文

我遇到了内存泄漏,但无法通过泄漏、构建/分析或整体检查来找出如何修复。我有一个非常强烈的想法,这是由于我的 UIWebview 加载 JavaScript 的 loadRequest 命令造成的,但我不知道出了什么问题。

这是我的设置:

我有一个 tabbarcontroller,我以编程方式创建了 4 个视图控制器:分别是一个表视图、一个地图视图、另一个表视图和一个 Web 视图。

  • 第一个表格视图显示静态数据。
  • 地图视图显示注释,单击时会填充第四个选项卡(Web 视图)的变量,并切换到 Web 视图以显示本地存储的 html/javascript 文件,该文件是 3D 模型
  • 第二个表视图是每个注释的所有相同信息的列表在mapview中表示,只是以表格形式。它在填充变量、在 web 视图中切换和显示 html/javascript 文件方面具有相同的功能。web
  • 视图显示加载的 html/javascript 文件,如果没有,它会显示 UIAlertView 以

在我时 从地图视图或列表中选择一个最后从 webview 执行 loadRequest() ,最初一切正常。但是,当我开始在选项卡之间切换并查看不同的 3D 模型时(即转到地图视图,单击注释以显示模型 x,观看它在 Web 视图中加载,然后切换到列表并单击一行以显示模型) y(或 x )并观察它在 web 视图中加载)我开始在 ipad 上收到内存泄漏,而不是模拟器。这些内存泄漏几乎总是:General-Block 56, 1024, 8, 244 & 24 并且没有负责的框架、库或堆栈跟踪可供跟踪。

在网络视图中,如果我注释掉 loadrequest 行或使用 request object = 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
  • 来自我评论过的上一篇文章,但没有收到回复 (通用块内存泄漏)我相信问题与以下事实有关:当我切换视图时,webview 不知道如何完全摆脱 javascript
  • 我用一个没有 javascript 的简单 html 文件进行了测试,一般情况-块内存泄漏消失了。但是,我收到其他 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 周的时间来解决这个问题,如果您能给我任何见解,我将非常感谢。

谢谢!

-麦克风

I'm getting memory leaks that i can't figure out through leaks, build/analyze or overall inspection how to repair. I have a very strong notion that it's due to the loadRequest command from my UIWebview loading javascript, but I can't figure out what's wrong.

Here's my setup:

I have a tabbarcontroller that i programatically create with 4 view controllers: a table view, a mapview, another table view and a webview, respectively.

  • the 1st tableview shows static data.
  • the mapview shows annotations that when clicked populates a variable of the 4th tab, the webview, and switches to the webview to display a locally stored html/javascript file that is a 3d model
  • the 2nd tableview is a listing of all the same information each annotation in the mapview represents, just in table form. it has the same functionality in terms of populating the variable, switching and displaying the html/javascript file in the webview
  • the webview displays the html/javascript file loaded, if not it shows a UIAlertView to select one from the mapview or the list

when i finally get to executing the loadRequest() from the webview, initially everything works fine. however, when i begin to switch between tabs and view different 3d models (i.e. go to the map view click an annotation to show say model x, watch it load in the webview, then switch to the listing table and click a row to show model y (or x too) and watch it load in the webview) i start receiving memory leaks on the ipad, not the simulator. these memory leaks are almost always: General-Block 56, 1024, 8, 244 & 24 and have no responsible frames, libraries or stack traces to follow up with.

in the webview if i comment out the loadrequest line or do a loadrequest with the request object = nil, i have no memory leaks, but when i switch to using a url object that points to the local files (i even tried pointing it to google.com, which has javascript) it erupts in memory leaks.

i've attempted to do each of these:

  • [self.webView loadRequest:nil];
  • [self.webView loadHTMLString:@"" baseURL:nil];
  • [self.webView stopLoading];

in viewWillDisappear of my webViewController in attempt to completely clean out the webview for reuse in the future, but it doesn't seem to be doing much help. i've also attempted doing this prior to doing the loadRequest but i get the same memory leaks.

  • fyi, i'm running the latest xcode 4.0.2 and the ipad has the latest update, 4.3.2
  • from a previous post i commented on and haven't heard back from (general-block memory leak) i believe the problem has to do with the fact that webview doesn't know how to fully rid itself of the javascript when i switch views
  • i did a test with a simple html file with no javascript and the general-block memory leaks are gone. however, i get other cfnetwork / http message memory leaks but that's a different story and not of my concern at the moment.

below is example code of when one of the annotations on the mapView is clicked which triggers the loadModel function in the webViewController:

- (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];

below is my 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];
}

if you have any advice or corrections, i'd greatly appreciate it. i have < 1 week to figure this out and would highly thank you if you could give me any insight.

thanks!

-Mike

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

琴流音 2024-11-09 08:22:40

迈克,我不知道你是有意还是无意地关注了?

- (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?
} 

Mike, I am not sure whether you are doing following intentionally or by mistake?

- (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?
} 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文