iPhone 内存管理和错误访问
我对堆栈溢出的许多问题都显示了我对 iPhone sdk 内存管理的失望。看来我已经修复了所有主要泄漏,但似乎存在这个很难称为泄漏的问题。根据我创建某些对象时的分配图,例如下面的翻转视图代码,该图不会下降到创建对象之前的位置,但确实下降了一点。我认为它下降的一点点是来自类释放的对象。对我来说奇怪的是,下次分配我的另一面视图时,图表不会像我认为的泄漏那样跳起来。例如,假设我的应用程序以 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
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 is 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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
看起来有点奇怪的是,您释放了 nav_bar,然后编写了以下内容...
[nav_bar pushNavigationItem:itemAnimated:NO];
您关于保留计数的逻辑是正确的,但一旦释放 nav_bar 该变量,就可以逻辑思考不再引用对象。
您应该大胆地释放它,但最后一旦完成所有操作。即使在 dealloc 中释放它也可以。
在这里,您对 nav_bar 的保留计数的想法是正确的,但是在您拥有的 nav_bar 的两个引用中,只有另一个由视图拥有,并且视图将释放它。所以释放你在 dealloc 函数中的部分就足够了。
希望这对您有帮助......
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.....