从超级景观中删除视图iOS
我很努力地理解为什么下面的第一种方法可以隐藏和删除视图的子视图。在这第一种方法中,我通过引用传递指针。在第二种方法中,我不太一般,我有一个用于删除特定视图的委托方法。我想使用第一种方法,因为我有几个我想要应用的视图。我应该提到,只要第一种方法在实现类中被调用,第一种方法就不会失败。当我从视图控制器中调用它时,它会失败,我想解雇它。当第一个方法失败时,我在removeFromSuperview行上得到EXC_BAD_ACCESS。从超级景观中删除视图iOS
-(void)closeView:(UIViewController **)viewController
{
[UIView transitionWithView:self.view
duration:UINavigationControllerHideShowBarDuration
options:UIViewAnimationOptionCurveLinear
animations:^
{
[[*viewController view] setAlpha:0.0];
}
completion:^(BOOL finished)
{
[[*viewController view] removeFromSuperview];
[*viewController release], *viewController = nil;
}];
}
-(void)closeButtonClicked
{
[delegate closeView:&self];
}
//
// This method works without fail:
//
-(void)closeView
{
[UIView transitionWithView:self.view
duration:UINavigationControllerHideShowBarDuration
options:UIViewAnimationOptionCurveLinear
animations:^
{
// In this context viewController is defined in the class interface
[[viewController view] setAlpha:0.0];
}
completion:^(BOOL finished)
{
[[viewController view] removeFromSuperview];
[viewController release], viewController = nil;
}];
}
-(void)closeButtonClicked
{
[delegate closeView];
}
首先,它不是根据风格指南,而不是一般的好主意,在这样的方法中执行viewController的发布。它会让你很快陷入麻烦。如果此方法的调用者负责viewController(它已完成保留),那么它也应该释放它。这很可能是第一种方法不能在viewcontroller内工作的原因。
在第二种方法中,您不传入viewController作为参数,这意味着它需要在上下文中定义。
如果你没有在这个方法中释放的viewController,那么你就需要设置其可变为零或者,你可以简单地把它作为正常的参数:
-(void)closeView:(UIViewController *)viewController
{
[UIView transitionWithView:self.view
duration:UINavigationControllerHideShowBarDuration
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^
{
[[viewController view] removeFromSuperview];
}
completion:nil];
}
那么您需要为此在调用点:
[self closeView:childViewController];
[childViewController release]; childViewController = nil;
动画完成之前,它安全地释放孩子以这种方式,因为动画阻止含蓄保留了块,包括参数的viewController引用的所有对象。因此,在动画块释放它之前,不会调用该子的dealloc。 这不适用于您的第一个代码示例,因为您将指针传递给变量。也就是说,动画块不知道它需要保留孩子。
顺便说一句,我不知道你为什么要设置alpha,在上面的例子中我显示你也可以删除已经在动画块中的视图。在UIView Class Reference中查看更多内容。
** viewcontroller和&自我不是要走的路。在Objective-C中,你在子视图本身中执行[self.view removeFromSuperview]
,在你做的release
的父视图控制器中,或者用ARC只是用另一个视图替换子视图。
感谢您的建议,我在上面留下了详细的评论,解释我的立场。你能否在所写的内容中澄清你的?)? – banDedo 2012-01-06 21:39:09
谢谢你关于不需要alpha的建议。这是个好消息。让我再解释一下我的推理,让你明白我为什么要发布正在被删除的视图。我这样做是为了将操作的处理从正在显示的子视图中分离出来。我希望父母的看法决定如何处理孩子。我不希望此操作的默认操作是删除和取消子视图。据说,我不明白为什么父母从视图中删除一个孩子并使其失效,这是有问题的。你能解释一下:) – banDedo 2012-01-06 21:36:44
就像一个额外的评论,removefromsuperview没有在块中动画。我仍然必须将它放入带有alpha动画的完成块中,才能按照需要工作。难道我做错了什么? – banDedo 2012-01-07 00:44:22
@PatrickHogan对不起,我应该适当地修改你的代码。对于选项:您需要选择其中一个UIViewAnimationOptionTransition选项,以使动画适用于已移除的视图。 CrossDissolve可能是你想要的。我将调整代码以表明这一点。 – fishinear 2012-01-07 02:13:26