导航控制问题

发布于 2024-11-23 17:00:49 字数 2537 浏览 0 评论 0原文

我正在使用一些方法加载新的 .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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

凉栀 2024-11-30 17:00:49

尝试在视图控制器上使用 autorelease

GameViewController* game = [[[GameViewController alloc initWithNibName:@"GameViewController" bundle:nil] autorelease];

导航控制器将获得传递给它的视图控制器的所有权,因此您不必保留对它的引用。但是你不能一遍又一遍地分配 GameViewControllers 而不释放它们。 autorelease 对此很有用。如果您愿意,您也可以在将其传递给导航控制器后释放它:

GameViewController* game = [[GameViewController alloc initWithNibName:@"GameViewController" bundle:nil];
[self.navigationController pushViewController:game animated:NO];
[game release];
game = nil;

编辑:
因此,如果您已经释放了 game 对象,那么它一定是 GameViewController 类本身内的内存泄漏。

您在 GameViewController 类中分配、复制或保留的任何内容都应该在 dealloc 方法中释放(也可能在 viewDidUnload 方法中释放)如果您在 viewDidLoad 方法中进行分配/复制/保留)。

iOS 内存管理编程指南可能会有所帮助。

如果您想发布 GameViewController 类中的相关代码,我相信有人能够帮助您确定内存泄漏。

您还可以尝试 仪器

编辑2:

我假设你有几个IBOutlets 连接到您的 GameViewController 类中的属性...

不知道您是否已经这样做了,但是在您的 viewDidUnload 方法中并且在您的dealloc方法中,您必须将所有这些IBOutlets属性设置为nil才能释放它们,如下所示:

- viewDidUnload
{
    //... whatever comes before

    self.timeLabel = nil;
    self.NumberLabel  = nil;
    //... etc
}
- dealloc
{
    //... whatever comes before

    self.timeLabel = nil;
    self.NumberLabel  = nil;
    //... etc

    [super dealloc];
}

一般来说,如果您有使用声明的任何属性>retain,这意味着当你设置该对象将被保留的属性。如果您将该属性设置为nil,则那里的对象将为您released。因此,任何带有 retain 关键字的属性都应设置为 nil (或释放支持 ivar)。

try autorelease on your view controller:

GameViewController* game = [[[GameViewController alloc initWithNibName:@"GameViewController" bundle:nil] autorelease];

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:

GameViewController* game = [[GameViewController alloc initWithNibName:@"GameViewController" bundle:nil];
[self.navigationController pushViewController:game animated:NO];
[game release];
game = nil;

EDIT:
So if you're already releasing the game object, then it must be a memory leak within the GameViewController class itself.

Annything you alloc, copy or retain in your GameViewController class you're supposed to release in the dealloc method (and maybe also in the viewDidUnload method if you're alloc/copy/retaining in the viewDidLoad 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 your GameViewController class...

don't know if you're already doing this, but in your viewDidUnload method AND on your dealloc method you have to set all of these IBOutlets properties to nil in order to release them, like so:

- viewDidUnload
{
    //... whatever comes before

    self.timeLabel = nil;
    self.NumberLabel  = nil;
    //... etc
}
- dealloc
{
    //... whatever comes before

    self.timeLabel = nil;
    self.NumberLabel  = nil;
    //... etc

    [super dealloc];
}

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 to nil, the object that was there will be released for you. So any properties with the retain keyword should be set to nil (or the backing ivar released).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文