2012-03-10 47 views
1

首先抱歉我的英文:-)不太好。在Window中奇怪的内存泄漏:addSubView

我有一个奇怪的内存泄漏与下面的代码(解释后的代码)。 我有一个类,FLWaitingView。这是一个简单的视图,带有等待指示符(加上带背景的视图),用于对用户说“等待数据加载”。 它有两个简单的方法:显示和解雇。 在show方法中,我找到主应用程序窗口并添加子视图(等待视图和背景视图,以不同的动画)。在解雇方法中,我将其从超级视角中移除。 在每个节目中,我使用静态布尔变量(is_visible)验证视图不可见。

奇怪的是这样的:在解雇方法,我用:

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

删除从窗口两种观点,以避免它们被保留。他们被正确地删除,我可以用NSLog验证这一点(在每个窗口子视图上的cicle)。但是,在INSTRUMENTS中,使用“mark heap”函数,我发现在每次重新加载(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]; 

(显然除去的冗余码从解雇法):

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

内存被正确释放。 为什么?????? 预先感谢您

法比奥

回答

0

你的观点并没有得到释放,你会因为你释放的那一刻仍然有链接到它的动画期待。您只能在动画完成后正确释放它。

您的第二种方法是可行的,因为动画持续时间少于0.5秒 - 释放代码在视图释放所有动画之后调用。

以动画的观点正确的方法是要么创建一个动画,并指定其委托或者也许有点更优雅soulution是使用基于块的动画是这样的:

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

这工作太(无记忆泄漏),就像我的其他“workaroud”,但我不明白为什么:-)。第一个代码有什么问题?意见似乎是正确地从主窗口中删除...但没有发布... – LombaX 2012-03-10 13:35:36

+0

@LombaX:我编辑了我的答案,一些解释 – 2012-03-10 14:12:54

+0

非常感谢!现在我明白了:-)移动到基于块的动画! – LombaX 2012-03-10 14:22:12