如何删除不再需要的视图控制器?

时间:2011-04-28 13:47:58

标签: ios objective-c cocoa-touch rootviewcontroller

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

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

        }
    }

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

我想完全破坏视图控制器,因为我只想在内存中有一个视图控制器。我计划每次从头开始创建视图控制器,如上面的代码所示。我这样做不正确吗?

2 个答案:

答案 0 :(得分:2)

这里的问题似乎是你没有发布视图控制器。想想代码中实际发生的事情:

[self.radarViewController.view removeFromSuperview];

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

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

如果要终止整个视图控制器,请在从超级视图中删除视图后调用此方法:

[self.radarViewController release];

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

self.radarViewContoller = nil;

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

释放视图控制器时,其引用计数减1。如果引用计数达到零,则将取消分配控制器。

答案 1 :(得分:0)

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

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

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