在我的场景中,将 removeFromSuperview 发送给自己并没有释放自己

Sending removeFromSuperview to self didn't release itself in my scenario

我有一个父视图 UIView 和一个 UITextView 作为子视图之一。 我创建了一个按钮来关闭父级 UIView,如下所示:

-(void)cancelButtonPressed:(UIButton *)sender
{
    [UIView animateWithDuration:0.2 delay:0.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
    self.frame = CGRectZero;
    } completion:^(BOOL finished) {
        if (finished) {
            [self removeFromSuperview];
        }
    }];
}

我可以看出父 UIView 没有被释放,因为如果我在 UITextView 中输入一些文本并关闭它,当我再次打开 UIView 时,相反空白 UITextView,里面又出现了相同的文字。

我检查了 Leaks 工具,但没有看到任何泄漏。所以我猜我是否有某种保留周期或什么。

更新:我有另一个对象(即 AppDelegate)持有 UIView 的实例:_myView 作为全局变量,如下所示:

_myView = [[MyView alloc] init];

_myView.nameLabel.text = _user.screen_name;
[_window addSubview:_myView];

[UIView animateWithDuration:0.2 delay:0.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
    _myView.frame = CGRectZero;
} completion:nil];

但是为了避免保留循环,我应该像这样创建一个弱自我:__weak MyView *weakSelf 并在动画块中这样做:[weakSelf removeFromSuperview]?

我也试过在视图本身上调用 removeFromSuperview,但并没有导致视图被释放。

如果要释放视图,请采用使用委托的方法。这样,一旦动画完成,您就可以在视图上调用 removeFromSuperview,并将其设置为 nil。这在过去对我有用。

因此,您可以向要关闭动画的视图 class 添加一个方法,您将在其中执行动画。将您的视图控制器设置为视图的委托,并从该动画的完成块中调用委托上的一些方法。

您可以为此创建自己的协议。如果你让它足够通用,并且只关注动画回调,你可以在你所有的视图控制器中重用该协议。

内存管理和逻辑是独立的东西。内存泄漏 永远不会 改变程序的行为。显示某些内容等行为由您告诉它显示的内容控制。如果它显示与以前相同的内容,那么您必须给它相同的内容以某种方式显示。即使你以某种方式泄露了原来的东西,如果你传递一个新的东西给它显示,它也会显示那个东西。所以看看你的逻辑。内存管理与您所看到的无关。