【发布时间】:2011-03-15 20:12:17
【问题描述】:
我正在尝试使用视图模拟翻书页。当查看打开的书时,每个 UIView 显示两个页面(左和右)。翻页时,应该显示一个新的 UIView。我目前的方法是使用带有空白根 UIView 的自定义 UIViewController 并将页面设置为子视图。当我添加一个新的子视图时,我会从添加的最后一个子视图过渡到新的子视图。转换完成后,我想删除之前的最后一个子视图,因为它不再需要 - 它不再可见并占用内存。
本质上是这样的:
UIView * myOldPageView = [[self.view subviews] lastObject];
[self.view addSubview:myNewPageView];
// ... transition between the two views
[myOldPageView removeFromSuperview];
这是我最初的尝试,但由于没有堆栈跟踪的神秘崩溃而失败。这个方法在我自定义的 UIViewController 中:
-(void) switchToController:(UIViewController *) controller {
[controller viewWillAppear:YES];
if (self.currentScreenController != nil) {
[self.currentScreenController viewWillDisappear:YES];
}
[self.view addSubview:[controller view]];
if (self.currentScreenController != nil) {
[[self.currentScreenController view] removeFromSuperview];
[self.currentScreenController viewDidDisappear:YES];
}
self.currentScreenController = controller;
[controller viewDidAppear:YES];
}
在此方法调用后执行[controller release] 会导致崩溃,这很奇怪,因为保留计数大于 0。如果我不执行释放,我会出现内存泄漏。
[编辑] 这是另一种不使用控制器的方法,当旧页面视图从其父视图中删除时会崩溃:
-(void) switchToView:(UIView *) screen {
[self.view addSubview:screen];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:screen cache:NO];
[UIView commitAnimations];
if (3 < [[self.view subviews] count]) {
[[[self.view subviews] objectAtIndex:0] removeFromSuperview]; // <- crash
}
}
[编辑]即使我尝试在添加新子视图后立即删除它,我也会崩溃,没有过渡动画:
-(void) switchToView:(UIView *) screen {
[self.view addSubview:screen];
if (3 < [[self.view subviews] count]) {
[screen removeFromSuperview]; // <- crash
}
}
[Edit] 我现在坚信问题在于释放添加的视图,这意味着它与动画或视图控制器无关。
【问题讨论】:
-
[myOldPageView removeFromSuperview];也可以
-
您是否开启了 NSZombieEnabled 以防万一?
-
@Nick 我没有结果。我开始认为两个控制器之间存在公共视图所有权的内部冲突——只有一个控制器可以拥有一个视图,而这里的根控制器和参数控制器都将拥有同一个视图。尽管如此,我仍然需要一个解决方案。
-
你能再指出一些为什么你必须切换到不同的 UIViewController 吗?你先说每个页面都是一个UIView,我现在有点糊涂了。
-
尝试添加一个 beginAnimations:context 来完成动画。控制台现在是否产生更具描述性的错误消息?
标签: iphone uiview uiviewcontroller