【问题标题】:Navigation Control Problem导航控制问题
【发布时间】:2011-07-13 22:20:27
【问题描述】:

我正在使用一些方法来加载新的 .xib 并返回主菜单。然而,大约五次后,它因使用过多的内存而崩溃。我需要能够多次返回主菜单和游戏。我应该为导航控件使用的任何其他方法。

主菜单部分:

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

返回主菜单的游戏部分:

[self.navigationController popViewControllerAnimated:NO];

这里是 viewdidLoad { - (void)viewDidLoad { [超级视图DidLoad]; [自启动定时器];

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];

}

}

【问题讨论】:

  • 在再次分配之前,你是否释放了game

标签: objective-c navigation controls


【解决方案1】:

在您的视图控制器上尝试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 方法中释放) 987654332@方法)。

如果您想了解更多细节,iOS Memory Management Programming Guide 可能会有所帮助。

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

您也可以尝试Instruments中的泄漏工具

编辑 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)。

【讨论】:

  • 好的,你没有在你发布它的地方发布你的代码的任何部分......我认为如果你遇到内存泄漏问题,这将是相关的。您可以在您发布的部分之后立即发布代码的一部分,您在哪里发布game
  • 那么我认为这是您的 GameViewController 类中的内存泄漏。如果您可以编辑原始问题并发布该课程的一些相关代码,那么有人可能会提供帮助。
  • 哦,如果您将 removeFromSuperview 添加到导航控制器中,您不应该调用它...导航控制器将负责执行转换和删除视图。但我不认为这会导致泄漏。
  • 不要当我返回主菜单时它会释放 GameViewController 类使用的所有内存
  • 抱歉 removeFromSuperview 不是正确的代码。我正在测试另一种启动视图的方式。既使用导航控制器,又添加和删除视图。
猜你喜欢
  • 2012-06-11
  • 1970-01-01
  • 2015-05-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多