iPhone内存管理和访问不良

时间:2011-09-05 17:08:24

标签: iphone memory-management memory-leaks allocation

我对堆栈溢出的许多疑问都表明我对iPhone sdk的内存管理感到沮丧。似乎我已经修复了所有主要泄漏,但似乎有这个问题难以称之为泄漏。根据我的分配图,当我制作certian对象时,例如下面的翻转视图代码,图形不会下降到对象制作之前的位置,但它确实下降了一点。我认为它失败的一点是来自班级释放的对象。对我来说似乎很奇怪的是,下次我的翻转视图被分配时,图形不会像我认为的泄漏那样跳起来。例如,假设我的应用程序从说1mb内存使用开始,然后当显示翻转视图时,一旦翻转视图被释放,它会跳到3mb,然后下降到2mb,但是下次呈现时它会回到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

1 个答案:

答案 0 :(得分:1)

看起来有点奇怪的是你发布了nav_bar然后你写了以下内容......

[nav_bar pushNavigationItem:item animated:NO];

关于保留计数的逻辑是正确的,但在逻辑上思考一旦释放nav_bar,该变量不再引用对象。

你应该挑衅地释放它,但最后一旦完成所有操作。即使以dealloc发布它也会。

在这里你对nav_bar的retainCount的思考是正确的,但是你认为nav_bar的两个参考只有一个由视图拥有,而视图将会释放它。所以在dealloc函数中释放你的部分就足够了。

希望这有用.....