1

我正在使用我的应用程序委托在视图控制器之间进行转换。当委托决定不再需要视图控制器时,根据来自服务器的消息,它需要删除当前视图并用另一个视图替换它。目前我的代码如下所示:

- (void) showFight: (NSNotification*) notification
    {
        if(self.window.rootViewController != self.fightViewController)
        {
            NSDictionary* dict = [notification userInfo];

                FightViewController *fightView = [[FightViewController alloc]
                                                  initWithNibName:@"FightViewController" bundle:nil];
                fightView.userId = _userId;

                self.fightViewController = fightView;
                [fightView release];
                [self.radarViewController.view removeFromSuperview];  // Doesn't work.

                self.window.rootViewController = self.fightViewController;
                [self.fightViewController showMonster:dict];

        }
    }

我知道我的视图控制器没有被删除,因为我可以在后台听到它的声音效果。

我想完全销毁视图控制器,因为我只想要一个视图控制器在内存中。我计划每次都从头开始创建视图控制器,如上面的代码所示。我这样做是否不当?

4

2 回答 2

2

这里的问题似乎是您没有释放视图控制器。想想在你的代码中实际发生了什么:

[self.radarViewController.view removeFromSuperview];

您从其超级视图中删除该视图。视图控制器仍然存在,它的作用是控制视图上应该显示的内容,并且在您的情况下显然是在播放声音。

简单地说:视图控制器是一个对象。它有一个孩子,观点。那是另一个对象。您从另一个视图中删除视图,但控制已删除视图的对象仍然存在(实际上,视图对象也是如此)。

如果要杀死整个视图控制器,请在从其父视图中删除视图后调用它:

[self.radarViewController release];

或者,如果视图是一个保留属性(我通过查看您的代码来假设),您也可以使用:

self.radarViewContoller = nil;

它会在合成的 setter 中自动为您释放。

当视图控制器被释放时,它的引用计数减一。如果引用计数达到零,则控制器将被释放。

于 2011-04-28T13:59:54.333 回答
0

到目前为止,我了解您的问题是在服务器通知上添加新的 ViewController 并使用新的View更改当前视图。首先,您必须像下面一样添加视图控制器,因为引用无助于更新视图。

[self.window.rootViewController.view addSubview: self.fightViewController.view]

在我看来,您需要标记您的控制器并在添加控制器之前检查它是否已存在于内存中,否则对象池将泄漏。对内存泄漏说不!

- (void) showFight: (NSNotification*) notification
{
      UIView *fightView = (UIView *)[self.window.rootViewController.view viewWithTag: FIGHT_VIEW_TAG];
      if (self.window.rootViewController.view.tag  != fightView.tag) {

          NSDictionary* dict = [notification userInfo];
          FightViewController *fightView = [[FightViewController alloc]
                                               initWithNibName:@"FightViewController" bundle:[NSBundle mainBundle]]; 

          //Remove the current view.
          [self.window.rootViewController.view removeFromSuperview];   // If you're adding the fighting View in the root View, then why are you trying to remove current view through radar controller which has already added in the window (root view). 

          fightView.userId = _userId;
          [fightView setTag: FIGHT_VIEW_TAG];
          [self.window.rootViewController.view addSubView: self.fightViewController.view]; 

          [self.fightViewController showMonster:dict];
          [fightView release];
  }
}

在您的要求不同之前,您不需要将它们视为全球性的。

于 2011-04-28T14:06:10.030 回答