导航控制问题
我正在使用一些方法加载新的 .xib 并返回主菜单。然而,大约五次后,它因使用过多内存而崩溃。我需要能够多次返回主菜单和游戏。我应该用于导航控件的任何其他方法。
主菜单部分:
GameViewController* game = [[GameViewController alloc initWithNibName:@"GameViewController" bundle:nil];
[self.navigationController pushViewController:game animated:NO];
游戏部分返回主菜单:
[self.navigationController popViewControllerAnimated:NO];
这里是viewdidLoad { - (void)viewDidLoad { [超级viewDidLoad]; [自启动定时器];
TotalSeconds = 0;
GameCenterTotalSeconds = 0;
timeSec = 0;
timeMin = 0;
Background = [[[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 480, 320)] autorelease];
Background.image = [UIImage imageWithContentsOfFile:[ [ NSBundle mainBundle] pathForResource:@"Background" ofType:@"png"]];
[self.view addSubview:Background];
timeLabel.textColor = [UIColor redColor];
[self.view addSubview:timeLabel];
NumberLabel = [[[UIImageView alloc] initWithFrame:CGRectMake(0, -4, 60, 70)] autorelease];
NumberLabel.image = [UIImage imageWithContentsOfFile:[[ NSBundle mainBundle] pathForResource:@"Number" ofType:@"png"]];
[self.view addSubview:NumberLabel];
QuestionNumber = [[[UILabel alloc] initWithFrame:CGRectMake(23, 17, 20, 20)] autorelease];
QuestionNumber.text = @"1";
QuestionNumber.textColor = [UIColor redColor];
QuestionNumber.backgroundColor = [UIColor clearColor];
[QuestionNumber setFont:[UIFont fontWithName:@"Marker Felt" size:30]];
[self.view addSubview:QuestionNumber];
numberLives = 1;
appDelegate = (OppositeMoronTestAppDelegate *)[[UIApplication sharedApplication]delegate];
musicButton = [[[UIButton buttonWithType:UIButtonTypeCustom] retain] autorelease];
musicButton.frame = CGRectMake(5, 283, 35, 35);
musicButton.backgroundColor = [UIColor clearColor];
if (appDelegate.shouldPlayMusic == YES) {
UIImage *Image = [UIImage imageWithContentsOfFile:[[ NSBundle mainBundle] pathForResource:@"MusicOn" ofType:@"png"]];
[musicButton setBackgroundImage:Image forState:UIControlStateNormal];
[musicButton addTarget:self action:@selector(TurnMusicOff) forControlEvents:UIControlEventTouchUpInside];
} else {
UIImage *Image = [UIImage imageWithContentsOfFile:[[ NSBundle mainBundle] pathForResource:@"MusicOff" ofType:@"png"]];
[musicButton setBackgroundImage:Image forState:UIControlStateNormal];
[musicButton addTarget:self action:@selector(TurnMusicOn) forControlEvents:UIControlEventTouchUpInside];
}
[self.view addSubview:musicButton];
[self showQuestion1];
}
}
I am using some methods to load a new .xib and go back to the main menu. However after about five time it crashes by using too much memory. I need to be able to go back to the main menu and to the game many times. Any other methods I should use for the navigation controls.
Main Menu part:
GameViewController* game = [[GameViewController alloc initWithNibName:@"GameViewController" bundle:nil];
[self.navigationController pushViewController:game animated:NO];
Game part to return to main menu:
[self.navigationController popViewControllerAnimated:NO];
Here is the viewdidLoad
{
- (void)viewDidLoad {
[super viewDidLoad];
[self StartTimer];
TotalSeconds = 0;
GameCenterTotalSeconds = 0;
timeSec = 0;
timeMin = 0;
Background = [[[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 480, 320)] autorelease];
Background.image = [UIImage imageWithContentsOfFile:[ [ NSBundle mainBundle] pathForResource:@"Background" ofType:@"png"]];
[self.view addSubview:Background];
timeLabel.textColor = [UIColor redColor];
[self.view addSubview:timeLabel];
NumberLabel = [[[UIImageView alloc] initWithFrame:CGRectMake(0, -4, 60, 70)] autorelease];
NumberLabel.image = [UIImage imageWithContentsOfFile:[[ NSBundle mainBundle] pathForResource:@"Number" ofType:@"png"]];
[self.view addSubview:NumberLabel];
QuestionNumber = [[[UILabel alloc] initWithFrame:CGRectMake(23, 17, 20, 20)] autorelease];
QuestionNumber.text = @"1";
QuestionNumber.textColor = [UIColor redColor];
QuestionNumber.backgroundColor = [UIColor clearColor];
[QuestionNumber setFont:[UIFont fontWithName:@"Marker Felt" size:30]];
[self.view addSubview:QuestionNumber];
numberLives = 1;
appDelegate = (OppositeMoronTestAppDelegate *)[[UIApplication sharedApplication]delegate];
musicButton = [[[UIButton buttonWithType:UIButtonTypeCustom] retain] autorelease];
musicButton.frame = CGRectMake(5, 283, 35, 35);
musicButton.backgroundColor = [UIColor clearColor];
if (appDelegate.shouldPlayMusic == YES) {
UIImage *Image = [UIImage imageWithContentsOfFile:[[ NSBundle mainBundle] pathForResource:@"MusicOn" ofType:@"png"]];
[musicButton setBackgroundImage:Image forState:UIControlStateNormal];
[musicButton addTarget:self action:@selector(TurnMusicOff) forControlEvents:UIControlEventTouchUpInside];
} else {
UIImage *Image = [UIImage imageWithContentsOfFile:[[ NSBundle mainBundle] pathForResource:@"MusicOff" ofType:@"png"]];
[musicButton setBackgroundImage:Image forState:UIControlStateNormal];
[musicButton addTarget:self action:@selector(TurnMusicOn) forControlEvents:UIControlEventTouchUpInside];
}
[self.view addSubview:musicButton];
[self showQuestion1];
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
尝试在视图控制器上使用
autorelease
:导航控制器将获得传递给它的视图控制器的所有权,因此您不必保留对它的引用。但是你不能一遍又一遍地分配 GameViewControllers 而不释放它们。
autorelease
对此很有用。如果您愿意,您也可以在将其传递给导航控制器后释放它:编辑:
因此,如果您已经释放了
game
对象,那么它一定是GameViewController
类本身内的内存泄漏。您在
GameViewController
类中分配、复制或保留的任何内容都应该在dealloc
方法中释放(也可能在viewDidUnload
方法中释放)如果您在 viewDidLoad 方法中进行分配/复制/保留)。iOS 内存管理编程指南可能会有所帮助。
如果您想发布 GameViewController 类中的相关代码,我相信有人能够帮助您确定内存泄漏。
您还可以尝试 仪器
编辑2:
我假设你有几个
IBOutlets
连接到您的GameViewController
类中的属性...不知道您是否已经这样做了,但是在您的
viewDidUnload
方法中并且在您的dealloc方法中,您必须将所有这些IBOutlets属性设置为nil才能释放它们,如下所示:一般来说,如果您有使用
声明的任何属性>retain
,这意味着当你设置该对象将被保留的属性。如果您将该属性设置为nil
,则那里的对象将为您released
。因此,任何带有retain
关键字的属性都应设置为nil
(或释放支持 ivar)。try
autorelease
on your view controller:The navigation controller will take ownership of the view controller passed to it, so you don't have to keep a reference to it. But you can't keep allocating GameViewControllers over and over without releasing them.
autorelease
is useful for that. You could also release it after you've passed it to the navigation controller if you prefer:EDIT:
So if you're already releasing the
game
object, then it must be a memory leak within theGameViewController
class itself.Annything you alloc, copy or retain in your
GameViewController
class you're supposed to release in thedealloc
method (and maybe also in theviewDidUnload
method if you're alloc/copy/retaining in theviewDidLoad
method).The iOS Memory Management Programming Guide might be helpful if you want to get into more detail.
If you want to post the relevant code from the
GameViewController
class, I'm sure someone will be able to help you pin down the memory leak.You can also try the Leaks tool in Instruments
EDIT 2:
I'm assuming you have several
IBOutlets
connected to properties in yourGameViewController
class...don't know if you're already doing this, but in your
viewDidUnload
method AND on yourdealloc
method you have to set all of theseIBOutlets
properties to nil in order to release them, like so:In general, if you have any properties declared with
retain
, that means that when you set that property the object will be retained. If you set that property tonil
, the object that was there will bereleased
for you. So any properties with theretain
keyword should be set tonil
(or the backing ivar released).