【问题标题】:iPhone memory management and bad accessiPhone 内存管理和错误访问
【发布时间】:2011-09-05 17:08:24
【问题描述】:

我关于堆栈溢出的许多问题都表明我对 iPhone sdk 上的内存管理感到沮丧。似乎我已经修复了我所有的主要泄漏,但似乎这个问题很难称之为泄漏。根据我在制作某些对象时的分配图,例如以下翻转视图代码,该图不会下降到创建对象之前的位置,但确实下降了一点。我假设它下降的一点是来自类释放的对象。对我来说似乎很奇怪的是,下次分配我的反面视图时,图表并没有像我认为的泄漏那样跳跃。例如,假设我的应用程序以 1mb 的内存使用量开始,然后当显示翻转视图时,一旦释放翻转视图,它就会跳到 3mb,但下一次显示它会回到 3mb 而不是 4mb .那是怎么回事?我读错了图表吗?我希望内存使用量回到 1 mb。当我的应用程序进入后台时,我也遇到了这个问题,并且我与其他一些应用程序混在一起,比如观看视频或浏览网页,这些应用程序使用内存。有时当我返回我的应用程序时,我会得到:

Program received signal: “EXC_BAD_ACCESS”.warning: Unable to read symbols for     
/Developer/Platforms/iPhoneOS.platform/DeviceSupport/4.3.3 
(8J2)/Symbols/Developer/usr/lib/libXcodeDebuggerSupport.dylib

我只是预感到这可能是相关的。

听到是我的反面示例的代码

在我的主视图控制器中

- (IBAction)showInfo
{
FlipsideViewController *controller = [[FlipsideViewController alloc] initWithNibName:nil bundle:nil];

controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:controller animated:YES];
[controller release];
}

我的翻转视图控制器

#import "FlipsideViewController.h"
#import "MainViewController.h"

@implementation FlipsideViewController

- (void)viewDidLoad {
    self.view.backgroundColor = [UIColor viewFlipsideBackgroundColor];

    nav_bar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0,0,self.view.frame.size.width+20,45)];
    // nav_bar retaincount 1
    [self.view addSubview:nav_bar];
    // nav_bar retaincount 2
    [nav_bar release];
    // nav_bar retaincount 1 - now controlled by self.view

    rightButton = [[UIBarButtonItem alloc] initWithTitle:@"Done" style:UIBarButtonItemStyleDone target:self action:@selector(done)];
    // rightButton retaincount 1

    item = [[UINavigationItem alloc] initWithTitle:@"Myapp Usage"];
    // item retaincount 1

    item.rightBarButtonItem = rightButton;
    // rightButton retaincount 2

    [rightButton release];
    // rightButton retaincount 1 - now controlled by item

    item.hidesBackButton = YES;
    [nav_bar pushNavigationItem:item animated:NO];
    // item retaincount 2

    [item release];
    // item retaincount 1 - now controlled by nav_bar

    web_view = [[UIWebView alloc]initWithFrame:CGRectMake(0,45,self.view.frame.size.width,self.view.frame.size.height - 45)];
    // web_view retaincount 1

    web_view.autoresizesSubviews = YES;
    web_view.autoresizingMask=(UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth);


    [web_view loadRequest:[NSURLRequest requestWithURL:
                          [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"Documentation" ofType:@"html"]isDirectory:NO]]];

    //[web_view loadRequest:requestObj];

    [self.view addSubview:web_view];
    // web_view retaincount 2

    [web_view release];
    // web_view retaincount 1 - now controlled by self.view

    [super viewDidLoad];
}

- (IBAction)done
{
    [self dismissModalViewControllerAnimated:YES];
    //[((MainViewController*)Controller) flipsideViewControllerDidFinish:self];
}

/*
 // Override to allow orientations other than the default portrait orientation.
 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
 // Return YES for supported orientations
 return (interfaceOrientation == UIInterfaceOrientationPortrait);
 }
 */

- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
//  [nav_bar removeFromSuperview];
    printf("Unloaded\n");
}


- (void)dealloc {
    [web_view loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"about:blank"]]];
    printf("Flipside Dalloc\n");
    //[web_view loadHTMLString: @"" baseURL: nil];
    //[web_view removeFromSuperview];
    //[rightButton release];
    NSLog(@"%d",[nav_bar retainCount]);
    [super dealloc];
}

@end

及其标题:

@interface FlipsideViewController : UIViewController {
    UIWebView    *web_view;
    UINavigationBar  *nav_bar;
    UIBarButtonItem  *rightButton;
    UINavigationItem *item;
}

- (IBAction)done;

@end

【问题讨论】:

  • 你为什么不在dealloc发布你的iVars?

标签: iphone memory-management memory-leaks allocation


【解决方案1】:

看起来有点奇怪的是,你释放了 nav_bar 然后你写了以下...

[nav_bar pushNavigationItem:item animated:NO];

您关于保留计数的逻辑是正确的,但在您释放 nav_bar 后逻辑上认为该变量不再引用对象。

你应该大胆地释放它,但最后一旦你完成了所有的操作。即使在 dealloc 中释放它也可以。

在这里,您对 nav_bar 的 retainCount 的想法是正确的,但是在您拥有的 nav_bar 的两个引用中,只有一个由 view 拥有,并且 view 将释放它。所以释放你在 dealloc 函数中的部分就足够了。

希望对您有所帮助.....

【讨论】:

  • 没有变化我确定它不是来自我的代码中的对象事实上我只是从实用程序应用程序向导生成的代码中看到了我正在谈论的问题。这很奇怪,因为它不会像我认为的那样发生泄漏,它只是分配图不会下降到它被释放后的位置。尝试创建一个实用程序应用程序并使用性能工具分配运行它当您按下完成时观看图表。对我来说它不会下降。那是怎么回事?
  • @Daniel - 使用泄漏仪器运行应用程序模板项目。我没有看到任何泄漏。我看到内存在增加,但那是因为资源已从 nib 文件中加载。
猜你喜欢
  • 2011-01-07
  • 2011-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-06
  • 2011-09-03
  • 1970-01-01
相关资源
最近更新 更多