我正在尝试为游戏创建一个多视图控制器,其中一个根视图控制器在切换到另一个视图之前释放视图。子视图控制器又是子视图控制器本身,因为它们包含其他视图控制器。
例如,我的singlePlayerViewController将有一个shakeObjectViewController,可能还有其他人。使用操作表在视图之间切换,将app delegate作为操作表的委托,从singlePlayer视图转到另一个视图时,一切都按预期工作。
但是当我尝试使用相同的init方法创建一个新的singlePlayerViewController时,当我尝试插入子视图时,调试器会抛出一个EXC _BAD
_ ACCESS错误,即shakeObjectViewController.view。
此时初始化看起来像这样: 应用程序委托使用默认的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];
后面是singlePlayerViewController.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不是插入子视图,而是用子视图控制器的视图替换它自己的视图。 (不知道这是不是一个好习惯:?:)
切换视图时,app委托执行以下操作:
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”上抛出错误线。 我的理解是,如果view属性当前为nil,则在下次访问视图时会自动为您创建一个新属性。
initWithNibName只能执行一次吗?或者我的设计方式在#view controllers方面太复杂了?
答案 0 :(得分:2)
注意我的singlePlayerViewController不是插入子视图,而是用子视图控制器的视图替换它自己的视图。 (不知道这是不是一个好习惯:?:)
这里有巨大的警告标志。听起来你有一个带有两个视图控制器的视图。这是不好的。
考虑插入和删除子视图:
这样你就有3个视图,有3个视图控制器。
这就是框架的使用方式。
答案 1 :(得分:0)
您的设计似乎有点过于复杂,但这并不意味着调试器应该抛出随机错误! :)尽管如此,试图简化它可能会有所帮助。如果您只是立即用摇动对象视图替换它,我不明白为什么您需要单个玩家视图。
我绝对认为你想将singlePlayerViewController设置为nil,因为否则rootViewControllers viewDidLoad方法中的行“if(singlePlayerViewController == nil){”将为false,并且不会创建新的视图控制器,这就是为什么你得到第一个错误。
我只看到3种方法可以在“self.view = shakeController.view”行上获得访问错误:
将self或shakeController设为nil不会导致错误,因为该行等同于
[self setView:[shakeController view]]
如果那些是零,则不会崩溃,因为允许消息为nil。
答案 2 :(得分:0)
是的,所有@property语句都标有(非原子,保留)。
也许这个问题可以重申,你如何不止一次从笔尖创建一个视图控制器?第二次创建VC时,无论是否释放同一类的前一个VC,都不会创建关联的视图,并且会抛出BAD ACCESS错误。
答案 3 :(得分:0)
你这样做的方式对我来说非常混乱,我认为对你的错误负责。我会逐行检查它并试图弄清楚它为什么会崩溃并且没有把它搞清楚,但与此同时我很难弄清楚切换期间视图发生了什么。/ p>
我会改写这个,因为Kailoa建议使用三个不同的视图控制器。每个视图都应该有自己的控制器。视图不应替换自身,应由超级视图控制器替换。
我怀疑她身上的某个地方正在被释放然后发出消息,然后你尝试对该消息的返回做一些事情,认为某事物是不是的对象。