Window中的奇怪内存泄漏:addSubView

时间:2012-03-10 12:39:41

标签: iphone objective-c

首先抱歉我的英语:-)不太好。

我有一个奇怪的内存泄漏与下面的代码(解释后的代码)。 我有一个类,FLWaitingView。这是一个带有等待指示器的简单视图(加上带背景的视图),用于对用户说“等待加载数据”。 它有两个简单的方法:show和dismiss。 在show方法中,我找到主应用程序窗口并添加子视图(等待视图和背景视图,具有不同的动画)。在dismiss方法中,我从superview中删除它。 在每个节目中,我使用静态bool var(is_visible)验证视图是否已经不可见。

奇怪的是:在解雇方法中,我使用:

[self.view removeFromSuperview];
[self.waitingView removeFromSuperview]; 

从Window中删除两个视图,以避免它们被保留。它们被正确删除,我可以使用NSLog验证这一点(对于每个窗口子视图上的cicle)。但是,在INSTRUMENTS中,使用“标记堆”函数,我看到在每次重新加载(FLWaitingView的新实例,然后显示,然后关闭)时,旧实例保留在内存中并继续增加内存使用量。显然不是调用代码的问题,因为我正确地释放了对象:

//CALLING CODE
//customWaitingView is a property retained
self.customWaitingView = [[[FLWaitingView alloc]init]autorelease];
[self.customWaitingView show];

而且,我认为这是最重要的信息,如果我在另一个方法中移动视图解除,由选择器调用,泄漏就会消失!!!

现在我显示“错误”代码,之后是“修正”。我想了解它为什么会发生。

- (void)show
{

    if (!is_visible){

        id appDelegate = [[UIApplication sharedApplication] delegate];
        UIWindow *window = [appDelegate window];
        self.waitingLabel.text = @"Attendere";

        self.view.alpha = 1.0;
        self.waitingView.alpha = 1.0;

        [window addSubview:self.view];
        [window addSubview:self.waitingView];
        [self.waitingIndicator startAnimating];
        self.view.frame = window.frame;
        self.waitingView.center = window.center;
        // "Pop in" animation for alert
        [self doPopInAnimationWithDelegate:self];
        // "Fade in" animation for background
        [self doFadeInAnimation];
        is_visible = YES;
    } else {
        NSLog(@"FLWaitingView %@ already visible, do nothing", self);
    }

}


- (void)dismiss
{
    [UIView beginAnimations:nil context:nil];
    self.view.alpha = 0.0;
    self.waitingView.alpha = 0.0;
    [UIView commitAnimations];
    [self.waitingIndicator stopAnimating];

    //here is the problem
    [self.view removeFromSuperview];
    [self.waitingView removeFromSuperview]; 
    is_visible = NO;
}

上面的代码是“错误的”,但如果我添加

[self performSelector:@selector(alertDidFadeOut) withObject:nil afterDelay:0.5];

在dismiss方法和一个新方法(显然从dismiss方法中删除冗余代码):

- (void)alertDidFadeOut
{      
    //here the memory is correctly released
    [self.view removeFromSuperview];
    [self.waitingView removeFromSuperview];
    is_visible = NO;
}

正确释放内存。 为什么?????? 提前谢谢

的Fabio

1 个答案:

答案 0 :(得分:0)

你的视图没有像你期望的那样被释放,因为在你发布它的那一刻,仍然有动画链接到它。您只能在动画完成后正确释放它。

你的第二种方法是有效的,因为动画持续时间不到0.5秒 - 在释放所有动画的视图后调用释放代码。

为视图设置动画的正确方法是创建动画并分配其委托,或者更优雅的方法是使用基于块的动画:

- (void)dismiss
{

    [[UIApplication sharedApplication] beginIgnoringInteractionEvents];                             

    [UIView animateWithDuration: 0.15
        animations: ^{
            self.view.alpha = 0.0;
            self.waitingView.alpha = 0.0;
                     }
        completion: ^(BOOL finished){
            [self.waitingIndicator stopAnimating];
            [self.view removeFromSuperview];
            [self.waitingView removeFromSuperview]; 
            is_visible = NO;    
            [[UIApplication sharedApplication] endIgnoringInteractionEvents];                             
        }];   
}