从superview iOS中删除视图

从superview iOS中删除视图,ios,animation,delegates,viewcontroller,Ios,Animation,Delegates,Viewcontroller,我正在努力理解为什么下面的第一种方法可以隐藏和删除视图的子视图。在第一个方法中,我通过引用传递指针。在第二种方法(不太通用)中,我有一个委托方法,用于删除特定视图。我想使用第一种方法,因为我有几个观点,我也想应用它。我应该提到,只要在实现类中调用第一个方法,它就不会失败。当我从视图控制器调用它时,它会失败,我希望关闭它。当在第一种方法中失败时,我在removeFromSuperview行上获得EXC_BAD_访问权限 -(void)closeView:(UIViewController **)v

我正在努力理解为什么下面的第一种方法可以隐藏和删除视图的子视图。在第一个方法中,我通过引用传递指针。在第二种方法(不太通用)中,我有一个委托方法,用于删除特定视图。我想使用第一种方法,因为我有几个观点,我也想应用它。我应该提到,只要在实现类中调用第一个方法,它就不会失败。当我从视图控制器调用它时,它会失败,我希望关闭它。当在第一种方法中失败时,我在removeFromSuperview行上获得EXC_BAD_访问权限

-(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和&self不是解决方法。在Objective-C中,您在子视图本身中执行
[self.view removeFromSuperview]
,在父视图控制器中执行
释放
或使用ARC只需将子视图替换为另一个视图即可。

首先,这不符合样式指南的要求,通常不是一个好主意,在这样的方法中释放viewController。这会很快给你带来麻烦。如果此方法的调用方负责viewController(它已经完成了保留),那么它也应该释放它。这可能是第一种方法无法在viewcontroller本身中工作的原因

在第二种方法中,不作为参数传入viewController,这意味着需要在上下文中定义它

如果不在此方法中释放viewController,则也不需要将其变量设置为nil,只需将其作为普通参数传递即可:

-(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参数。因此,直到动画块释放该子对象的解除锁定,才会调用该子对象的解除锁定。 这在您的第一个代码示例中不起作用,因为您传递了一个指向变量的指针。也就是说,动画块不知道它需要保留子对象


顺便说一句,我不知道为什么要设置alpha,在上面的示例中,我显示您也可以删除动画块中已经存在的视图。有关这方面的更多信息,请参阅。

感谢您提供的关于不需要alpha的建议。这是个好消息。让我再解释一下我的推理,以便您理解我为什么要释放被删除的视图。我这样做是为了将操作的处理与正在显示的子视图分离。我希望家长视图决定如何处理孩子。我不希望此操作的默认操作是删除并使子视图无效。尽管如此,我不明白为什么父母从视图中删除一个孩子并使其无效会有问题。您能解释一下吗:)作为添加的注释,removefromsuperview在块中没有动画。我仍然必须把它放在动画中的alpha完成块中,这样才能按预期工作。我做错什么了吗?@PatrickHogan很抱歉,我应该正确修改你的代码。对于选项:参数,您需要选择一个UIViewAnimationOptionTransition选项,以便将动画应用于删除的视图。交叉溶解可能是您想要的。我将对代码进行修改,以显示这一点。@PatrickHogan关于版本:父视图从视图中删除子视图没有错,而您只需使用removeFromSuperView即可。但是,将变量的地址传递给其他人并要求它为您释放并使其无效是非常令人困惑的。事实上,EXC_BAD_访问错误可能来自于此:您忘记了closeView现在负责发布,并且在动画运行时也在另一个地方发布了它(可能是父级的dealloc?)。“[*viewController视图]”引用了一个已经发布的对象。感谢您对转换的更新。此外,我在子视图的dealloc中放置了一个断点,在执行完成块之前不会调用该断点。存在完成块,以便在动画完成之前不会进行清理。我必须把地址传过去,这样我才能把它设为零。如果我只传递指针并释放它,一切正常。我仍然有点困惑,为什么这在这个案件中不起作用,但我想我会把它归咎于一个看不见的打字错误或逻辑错误,直到我找到更多的证据。谢谢你的跟进:)谢谢你的建议,我在上面留下了详细的评论来解释我的立场。你能在文中说明你的观点吗:)?