Iphone 如何在多视图控制器中正确释放和切换视图?

Iphone 如何在多视图控制器中正确释放和切换视图?,iphone,cocoa-touch,Iphone,Cocoa Touch,我正在尝试为游戏创建一个多视图控制器,其中一个根视图控制器在切换到另一个视图之前释放视图。子视图控制器本身又是子根视图控制器,因为它们包含其他视图控制器 例如,我的singlePlayerViewController将有一个shakeObjectViewController,可能还有其他控制器。使用actionsheets在视图之间切换,将应用程序委托作为actionsheet的委托,当从单机版视图切换到另一个视图时,一切都按预期进行 但是,当我尝试使用相同的init方法创建新的singlePl

我正在尝试为游戏创建一个多视图控制器,其中一个根视图控制器在切换到另一个视图之前释放视图。子视图控制器本身又是子根视图控制器,因为它们包含其他视图控制器

例如,我的singlePlayerViewController将有一个shakeObjectViewController,可能还有其他控制器。使用actionsheets在视图之间切换,将应用程序委托作为actionsheet的委托,当从单机版视图切换到另一个视图时,一切都按预期进行

但是,当我尝试使用相同的init方法创建新的singlePlayerViewController时,当我尝试插入子视图(即shakeObjectViewController.view)时,调试器会抛出EXC
\u BAD
\u访问错误

目前的初始化情况如下所示: 应用程序委托使用默认的init方法初始化窗口

- (void)applicationDidFinishLaunching:(UIApplication *)application {   
    // Override point for customization after application launch
   [window addSubview:rootViewController.view];
    [window makeKeyAndVisible];
}
然后在rootViewController.m的viewDidLoad中

   if(singlePlayerViewController == nil) {

      SinglePlayerViewController *singleController = [[SinglePlayerViewController alloc]
                                       initWithNibName:@"SinglePlayerView" bundle:nil];
      self.singlePlayerViewController = singleController;
      [singleController release];
   }

   [self.view insertSubview:singlePlayerViewController.view atIndex:0];
然后是singleplayervewcontroller.m

- (void)viewDidLoad {
   self.view.tag = kSinglePlayerView; // tag the view

   ShakeObjectViewController *shakeController = [[ShakeObjectViewController alloc]
                                       initWithNibName:@"ShakeObjectView" bundle:nil];
   self.shakeObjectViewController = shakeController;
   self.view = shakeController.view;
   [shakeController release];
}
请注意,我的singlePlayerViewController并没有插入子视图,而是将自己的视图替换为子视图控制器的视图。(不知道这是否是一种好的做法:?:)

切换视图时,应用程序代理执行以下操作:

for(UIView *subview in [rootViewController.view subviews])
{   
   [subview removeFromSuperview];
}
[rootViewController.singlePlayerViewController release]

[rootViewController initMultiplayerView];
然后,当切换回单人模式时,执行rootViewController.m的viewDidLoad中相同的init方法,调试器在“[self.view insertSubview:singlePlayerViewController.view atIndex:0]”行上抛出错误

有没有关于为什么没有创建新视图的想法?我尝试将singlePlayerViewController设置为nil而不是释放,但随后在“self.view=shakeController.view;”行中抛出错误。 我的理解是,如果视图属性当前为零,则在下次访问视图时会自动为您创建一个新属性


initWithNibName是否只执行一次?或者我的设计方式在“视图控制器”方面过于复杂?

您的设计看起来确实有点过于复杂,但这并不意味着调试器应该抛出随机错误!:)不过,尝试简化可能会有所帮助。我不明白为什么你想要一个单人视图,如果你要立即用一个抖动对象视图来代替它

我肯定认为您希望将singlePlayerViewController设置为nil,因为否则rootViewControllers viewDidLoad方法中的行“if(singlePlayerViewController==nil){”将为false,并且不会生成新的视图控制器,这就是为什么会出现第一个错误

在“self.view=shakeController.view”行中,我只看到了3种可能导致访问错误的方法:

  • shakeController不是nil,而是垃圾。这似乎不太可能,因为它只是初始化的,除非它的viewDidLoad释放自己或类似的东西
  • self不是nil,但是垃圾。同样,不太可能,但可能-可能检查调试器,看看self是什么样子(它的变量有意义吗,等等)
  • 当您调用self.view=…,它将向原始视图发送一个释放。单人视图的dealloc方法中是否有可能导致访问错误的代码
如果self或shakeController为nil,则不会导致错误,因为该行相当于

[self setView:[shakeController view]]

如果这些为nil,则不会崩溃,因为允许向nil发送消息。

是的,所有@property语句都标记为(nonatomic,retain)

也许问题可以重述为,如何从nib多次创建视图控制器?第二次创建VC时,无论是否释放同一类的先前VC,关联视图都不会创建,并抛出错误访问错误

请注意,我的singlePlayerViewController没有插入子视图,而是将自己的视图替换为子视图控制器的视图。(不知道这是否是一种好的做法:?:)

这里有巨大的警告标志。听起来好像你有一个视图和两个视图控制器。这很糟糕

请考虑插入和删除子视图:

  • 根视图
    • SinglePlayerView(可以删除并替换为MutliplayerView)
      • 沙克维尤
这样您就有了3个视图和3个视图控制器


这就是框架的使用方式。

你这样做的方式让我非常困惑,我认为这是你的错误的原因。我正在逐行检查,试图找出它崩溃的原因,但还没有完全弄清楚,但同时我很难弄清楚vie到底发生了什么切换过程中的ws

我会按照Kailoa的建议用三个不同的视图控制器来重写它。每个视图都应该有自己的控制器。一个视图不应该替换它自己,它应该被它的superview控制器替换


我怀疑她身上的某个地方有什么东西被释放了,然后被发送了消息,然后你试图通过返回该消息来做一些事情,认为某个东西是一个对象,而它不是。

singleplayer视图最终将在其他视图之间切换,而不仅仅是shake视图。尝试注释“如果”(SinglePlayerServiceController==nil)“行并实例化一个新的控制器。同样的错误。“NSLog(@“shake's view=%@”,shakeController.view);”,引发相同的错误。还尝试完全跳过singleplayer视图控制器,并在根控制器中直接使用shakeObject VC。相同的错误。如果我不尝试释放视图,则切换btw视图可以正常工作,但我每次都需要一个新视图。感谢回复。