一分钟后webview中的内存泄漏仅通过仪器

Posted

技术标签:

【中文标题】一分钟后webview中的内存泄漏仅通过仪器【英文标题】:memory leak in webview after one minute only by instrument 【发布时间】:2011-07-12 12:29:08 【问题描述】:

这是我的第一个 ios 应用程序,我遵循苹果文档和 *** 的答案,在 xcode 中,我的应用程序在模拟器和设备上都可以正常工作,但在仪器上,我在应用程序启动 50 到 70 秒后出现内存泄漏。

我使用带有 3 个视图控制器、3 个 webviews 的选项卡控制器,每个 webview 都显示一个这样的网页:

<html dir="rtl">
<head>
<meta http-equiv="Content-Language" content="en-us">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" href="newstyle.css" type="text/css" />
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="js/iphone.js"></script>
<title></title>
</head>
<body style="color:#FFFFFF">
<div align="center">
<table border="0"  id="table1" cellspacing="5">

<tr>
<form method="get">
<input type="hidden" name="index" value="<?=$_GET['index']?>">
<input type="hidden" name="cat" value="<?=$_GET['cat']?>">
<input type="hidden" name="area" value="<?=$_GET['area']?>">
<td class="search">
<div class="back"><a href="javascript:window.history.back()">back</a></div>
    <div class="srchbox"><a href="#reviews">&nbsp;<sub>notes (<?=countDataPages('iresturant_reviews','status=1 and clientIIndex ='.$_GET['index'].' and clientID='.$_GET['id'], 1);?>)</sub></a><div id="rates"><div id="actualrates" style="width:<?=round($mydatad[7] * 10)?>%"></div></div>
</td>
</form>
</tr>
    <tr>
    <td style="padding-left: 10px; padding-right: 10px" >
<div class="justBox" style="padding:10px;"> 
<b><?=unFormatData($mydata[1])?></b><br>
    <span style="font-weight: 400"><?=$catTitle[$mydata[3-$minusIndex]]?>
    <br><br>
    <?=$areaTitle[$mydata[4-$minusIndex]]?><br>
    <?=unFormatData($mydatad[3])?>
    </span>
        <p align="left" style="margin:0px;margin-top:15px;">
    <a href="page1.php?id=<?=$mydata[0]?>&index=<?=$_GET['index']?>"><img border="0" src="images/zx.png"  ></a>&nbsp;&nbsp;
        <a href="page2.php?id=<?=$mydata[0]?>&index=<?=$_GET['index']?>"><img border="0" src="images/xz.png"  ></a>
        </div></td>
    </tr>

    <tr>
    <td style="padding-left: 10px; padding-right: 10px">    
    <?
    $imgFile = 'uimages/index_'.$_GET['index'].'_'.$mydata[0].'.jpg';
    if (file_exists($imgFile))
    
    ?>

        <img src="<?=$imgFile?>"  align="right" style="margin-left:30px;"><p>
    <?
    
    ?></td>
    </tr>
            <tr>
    <td style="padding-left: 10px; padding-right: 10px"><br><br>
        <img border="0" src="images/phone.png"   align="absmiddle"> &nbsp; <?=unFormatData($mydata[5-$minusIndex])?><br>
        <img border="0" src="images/web.png"   align="absmiddle"> &nbsp; <?=unFormatData($mydatad[4])?></span>
    <br><br><?=unFormatData($mydatad[2])?>
    <p style="padding-right:10px;line-height:200%"  >
    </p><br>&nbsp;
</td>
    </tr>
<tr>
<td class="search">
    <div class="back"><a href="javascript:window.history.back()">back</a></div>
    <p style="margin-right: 10px; margin-top: 5px">
<a name="reviews"></a><font color="#FFFFFF">reviews</font>
</td>
</tr>       
<tr>
<td style="padding-left: 10px; padding-right: 10px" >
<?
    $data = getAllData('iphone_reviews','status=1 and clientIIndex ='.$_GET['index'].' and clientID='.$_GET['id'].' order by date desc');
for ($i=0; $i < sizeof($data); $i++)

?>  
<div class="justBox" style="padding:10px;"> 
<p style="margin:5px;"><?=unFormatData($data[$i][3])?></p>
<p dir="ltr" style="margin:0px;"><?=date("F j, Y h:i A", $data[$i][7])?></p>
<p style="margin:0px;font-weight: 400; padding:10px;"><?=unFormatData($data[$i][5])?></p>
</div>
<hr size="1">
<?

?>

</td>
</tr>   
<tr>
<td class="search">
    <div class="back"><a href="javascript:window.history.back()">back</a></div>
    <p style="margin-right: 10px; margin-top: 5px">
<font color="#FFFFFF">review</font>
</td>
</tr>
<tr><td style="padding-left: 10px; padding-right: 10px">
<div id="addFrm">
    <br>
    name<br>
    <input type="text" id="name" size="20" style="width:100%"><br>
    <br>
    review<br>
    <textarea rows="2" id="comment" cols="20"  style="width:100%; height:71"></textarea><br>
    <br>
    rate <?=$oTitle?><select size="1" id="rate">
    <?
    for ($i=10; $i > 0; $i--)
    
    echo '<option value="'.$i.'">'.$i.'</option>';
    
    ?>
    </select></span>
<span lang="ar-sy">from 10<br>
    <br>
    <button type="button" class="submitbutton" onclick="submitComment()">send</button></span></div></td></tr>   
<tr><td>&nbsp;</td></tr>    
</table>

使用 xcode > 应用程序在模拟器和设备上运行完美,完全没有错误。

使用仪器 > 如果我没有在 webview 中执行任何操作,则根本没有内存泄漏,当我开始在网页内单击并移动时,大约一分钟后我收到内存泄漏。

一开始,我以为是因为我同时运行 3 个 webview,但是当我在 1 个 webview 上进行测试时,出现了同样的问题。

这是我的代码:

#import "SecondSection.h"
#import "NamesViewController.h"
#import "TypesViewController.h"
#import "AreasViewController.h"


@implementation SecondSection


- (void)loadView 
UIView *contentView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
contentView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"bk.png"]];
self.view = contentView;
[contentView release];

// Declare all three view controllers
NamesViewController *NamesInfoController = [[[NamesViewController alloc] initWithNibName:@"DetailViewController" bundle:[NSBundle mainBundle]] autorelease];

TypesViewController *typesViewController = [[[TypesViewController alloc] init] autorelease];
AreasViewController *areasViewController = [[[AreasViewController alloc] init] autorelease];

// Set a title for each view controller. These will also be names of each tab
NamesInfoController.title = @"names";
typesViewController.title = @"types";
areasViewController.title = @"areas";

NamesInfoController.tabBarItem.image = [UIImage imageNamed:@"names.png"];
typesViewController.tabBarItem.image = [UIImage imageNamed:@"types.png"];
areasViewController.tabBarItem.image = [UIImage imageNamed:@"areas.png"];


// Create an empty tab controller and set it to fill the screen minus the top title bar
UITabBarController *tabBarController = [[UITabBarController alloc] init];
tabBarController.view.frame = CGRectMake(0, 0, 320, 460);

// Set each tab to show an appropriate view controller
[tabBarController setViewControllers:
 [NSArray arrayWithObjects:NamesInfoController, typesViewController, areasViewController, nil]];

// Clean up objects we don't need anymore
[NamesInfoController release];
[typesViewController release];
[areasViewController release];

// Finally, add the tab controller view to the parent view
[self.view addSubview:tabBarController.view];    


- (void)dealloc

[super dealloc];


- (void)viewWillDisappear





- (void)didReceiveMemoryWarning

// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];



#pragma mark - View lifecycle

- (void)viewDidLoad

[super viewDidLoad];


- (void)viewDidUnload

[super viewDidUnload];



- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation

return (interfaceOrientation == UIInterfaceOrientationPortrait);


@end

问题出在哪里? 我的第二个问题,也许它会帮助解决第一个问题,如何制作标签栏按钮,在第二次点击时从 url 请求加载 webview,解释更多:当我第一次点击标签栏按钮 1 时,它会加载一个视图控制器 1 加载加载 url 请求的 webview1,单击另一个选项卡按钮 2 然后返回选项卡按钮 1,它不会再次加载 webview1,它只会在您离开时显示它,因为与视图控制器相关的选项卡栏与 webview 无关。如何解决它。

感谢任何帮助

更新:@Alexander 这里是第二部分之前主窗口的示例代码:

- (IBAction)rests:(id)sender;

HUD = [[MBProgressHUD alloc] initWithView:self.navigationController.view];
[self.navigationController.view addSubview:HUD];
HUD.delegate = self;
HUD.labelText = @"Loading";
[HUD showWhileExecuting:@selector(myTask) onTarget:self withObject:nil animated:YES];
SecondSection *zcontroller = [[SecondSection alloc] init];
zcontroller.title = @"macaesar";
[[self navigationController] pushViewController:zcontroller animated:YES];
[zcontroller release];

【问题讨论】:

【参考方案1】:

我不太确定 webview 中的这种泄漏,因为您没有提供创建它们的方式,但您肯定必须在您的 loadView 类中使用 [super loadView] 并且您没有释放您的 tabBarController。我不太确定您在 SecondSection 课程之前使用了什么。 webView 加载怎么样,你应该让 webView 成为你的类变量,然后使用 UIViewController 方法中的事件 -(void)viewWillAppear:(BOOL)animated。不要忘记超级。

【讨论】:

感谢回复,在第二部分之前,主窗口控制器包含与第一部分和第二部分相关的 2 个按钮,并带有导航返回主窗口。我将使用示例代码更新问题。 在我的webview中,我使用[super viewDidLoad],我没有释放tabBarController,我只是将[super loadView]添加到第二部分类,没有任何反应。【参考方案2】:

Macaesar 试试这个:

1) 将您的视图控制器委托给您的 UIWebView。

2) 添加如下方法:

- (void)webViewDidFinishLoad:(UIWebView *)webView
    [[NSUserDefaults standardUserDefaults] setInteger:0 forKey:@"WebKitCacheModelPreferenceKey"];

它解决了我的泄漏问题。

【讨论】:

thanx @jacky,我已经在 viewcontroller 中设置了 UIWebView 委托,但我现在将您的代码添加到 webViewDidFinishLoad 并稍后回复您。 它没有解决它,一段时间后仍然有泄漏。感谢您分享您的代码。

以上是关于一分钟后webview中的内存泄漏仅通过仪器的主要内容,如果未能解决你的问题,请参考以下文章

使用仪器检查 xcode 4 中的内存泄漏

奇怪的内存泄漏

如何解决 iOS App 中的内存泄漏问题?

添加触摸事件时iOS webview中的内存泄漏

仪器中存在内存泄漏的类

内存泄漏仪器警告