iPhone memory management and bad access
So many of my questions on stack overflow display my frustration with memory management on the iPhone sdk. It seems that I have fixed all of my major leaks but there seems to be this problem that is hard to call a leak. According to my allocations graph when I make certian objects for example the following flipside view code, The graph does not go down to where it was before the object was made but it does go down a little. I assume the little bit that it goes down is from the objects being released by the class. What seems strange to me is that the next time my flipside view is allocated the graph does not jump way up like it would in what i would consider a leak. for example lets say my app starts at say 1mb mem usage then when the flipside view is presented it jumps up to 3mb once the flipside view is released it goes down to 2mb but the next time it is presented it goes back to 3mb instead of 4mb. whats up with that? Am i reading the graph wrong? I want the mem usage to go back to 1 mb. I am also having this problem when my app goes to the background and I mess around with some other apps say watch a video or browse the web something that uses memory. Sometimes when I return to my app I get:
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
I just have a hunch that it might be related.
hear i开发者_C百科s the code for my flipside example
In my main view controller
- (IBAction)showInfo
{
FlipsideViewController *controller = [[FlipsideViewController alloc] initWithNibName:nil bundle:nil];
controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:controller animated:YES];
[controller release];
}
my flipside view controller
#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
and its header:
@interface FlipsideViewController : UIViewController {
UIWebView *web_view;
UINavigationBar *nav_bar;
UIBarButtonItem *rightButton;
UINavigationItem *item;
}
- (IBAction)done;
@end
What looks bit strange is that you released nav_bar and then you wrote following...
[nav_bar pushNavigationItem:item animated:NO];
Your logic about retain count is right but logically thinking once you release nav_bar that variable no more refer to object.
You should defiantly release it but at last once you are done with all operations. Even releasing it in dealloc will do.
Here your thinking about retainCount of nav_bar is true but out of that two refrence of nav_bar you own only one other is owned by view and view will release it. So releasing your part in dealloc function will be enough.
Hope this is helpful.....
精彩评论