简体   繁体   English

从superview iOS中删除视图

[英]Removing view from superview iOS

I am struggling with understanding why the first method below works for hiding and removing a subview of a view. 我正在努力理解为什么下面的第一个方法可以隐藏和删除视图的子视图。 In this first method I pass the pointer by reference. 在第一种方法中,我通过引用传递指针。 In the second method, which is less general, I have a delegate method designed for removing a specific view. 在第二种不太通用的方法中,我有一个专门用于删除特定视图的委托方法。 I would like to use the first method, because I have several views that I would like to apply this too. 我想使用第一种方法,因为我有几个视图,我也想应用它。 I should mention that the first method works without fail as long as it is called within the implementing class. 我应该提一下,只要在实现类中调用它,第一种方法就可以正常工作。 It fails when I call it from the view controller that I wish to dismiss. 当我从视图控制器调用它时,它会失败,我想解雇它。 I get an EXC_BAD_ACCESS on the removeFromSuperview line when it fails in the first method. 当第一个方法失败时,我在removeFromSuperview行上获得了EXC_BAD_ACCESS。

-(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];
}

First of all, it is not according to the style guides, and not a good idea in general, to do a release of the viewController within a method like this. 首先,在这样的方法中发布viewController不是根据样式指南,而不是一般的好主意。 It will get you into trouble quickly. 它会让你很快陷入困境。 If the caller of this method is responsible for the viewController (it has done the retain), then it should release it as well. 如果此方法的调用者负责viewController(它已经完成了retain),那么它也应该释放它。 This is likely the cause of the first method not working from within the viewcontroller itself. 这可能是第一种方法无法在viewcontroller本身内工作的原因。

In the second method you do not pass in the viewController as parameter, which means it needs to be defined in the context. 在第二种方法中,您不会将viewController作为参数传递,这意味着它需要在上下文中定义。

If you don't release the viewController in this method, then you don't need to set its variable to nil either, and you can simply pass it as normal parameter: 如果你没有在这个方法中释放viewController,那么你也不需要将它的变量设置为nil,你可以简单地将它作为普通参数传递:

-(void)closeView:(UIViewController *)viewController
{
 [UIView transitionWithView:self.view 
                   duration:UINavigationControllerHideShowBarDuration
                    options:UIViewAnimationOptionTransitionCrossDissolve
                 animations:^
  {
    [[viewController view] removeFromSuperview];
  }
                 completion:nil];
}

you would then do this at the call-site: 然后你会在电话会议上这样做:

[self closeView:childViewController];
[childViewController release]; childViewController = nil;

It safe to release the child in this way before the animation is done, because the animations block implicitly retains all objects referenced from the block, including the viewController parameter. 在动画完成之前以这种方式释放子项是安全的,因为动画块隐式地保留从块引用的所有对象,包括viewController参数。 Therefore, the child's dealloc is not called until the animations block releases it. 因此,在动画块释放它之前不会调用子代的dealloc。 This does not work in your first code example, because you pass a pointer to a variable. 这在您的第一个代码示例中不起作用,因为您将指针传递给变量。 That is, the animations block does not know it needs to retain the child. 也就是说,动画块不知道它需要保留孩子。

BTW, I am not sure why you want to set the alpha, in the example above I show that you can also remove the view already in the animations block. 顺便说一句,我不确定你为什么要设置alpha,在上面的例子中我表明你也可以删除动画块中已有的视图。 See more about that in the UIView Class Reference . UIView类参考中查看更多相关信息。

**viewcontroller and &self is not the way to go. ** viewcontroller和&self不是要走的路。 In Objective-C, you do [self.view removeFromSuperview] in the subview itself, in the parent viewcontroller you do release or with ARC just replace the subview with another view. 在Objective-C中,您在子视图本身中执行[self.view removeFromSuperview] ,在您执行release的父视图控制器中,或者使用ARC将子视图替换为另一个视图。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM