从 iOS 超级视图中删除视图
我正在努力理解为什么下面的第一种方法适用于隐藏和删除视图的子视图。在第一个方法中,我通过引用传递指针。在第二种不太通用的方法中,我有一个委托方法,旨在删除特定视图。我想使用第一种方法,因为我有几个观点,我也想应用这个方法。我应该提到,只要在实现类中调用第一个方法,它就不会失败。当我从我希望关闭的视图控制器调用它时,它会失败。当第一种方法失败时,我在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];
}
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.
-(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];
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
首先,在这样的方法中释放 viewController 并不符合样式指南,而且一般来说也不是一个好主意。它很快就会让你陷入麻烦。如果这个方法的调用者负责viewController(它已经完成了retain),那么它也应该释放它。这可能是第一种方法无法在视图控制器本身内部工作的原因。
在第二种方法中,您不传入 viewController 作为参数,这意味着它需要在上下文中定义。
如果您没有在此方法中释放 viewController,那么您也不需要将其变量设置为 nil,并且您可以简单地将其作为普通参数传递:
然后您可以在调用站点执行此操作
:在动画完成之前以这种方式释放子级,因为动画块隐式保留了该块引用的所有对象,包括 viewController 参数。因此,直到动画块释放子进程的 dealloc 后,才会调用它。
这在您的第一个代码示例中不起作用,因为您传递了指向变量的指针。也就是说,动画块不知道它需要保留子对象。
顺便说一句,我不确定你为什么要设置 alpha,在上面的示例中我展示了你也可以删除动画块中已有的视图。有关详细信息,请参阅 UIView 类参考。
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. 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. This is likely the cause of the first method not working from within the viewcontroller itself.
In the second method you do not pass in the viewController as parameter, which means it needs to be defined in the context.
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:
you would then do this at the call-site:
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. Therefore, the child's dealloc is not called until the animations block releases it.
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. See more about that in the UIView Class Reference.
**viewcontroller 和 &self 不是正确的选择。在 Objective-C 中,您可以在子视图本身中执行
[self.view removeFromSuperview]
操作,在父视图控制器中执行release
操作,或者使用 ARC 将子视图替换为另一个视图。**viewcontroller and &self is not the way to go. In Objective-C, you do
[self.view removeFromSuperview]
in the subview itself, in the parent viewcontroller you dorelease
or with ARC just replace the subview with another view.