iPhone Instruments Leaks令我困惑。 UIView淡出动画会导致很多微小的泄漏

时间:2009-11-23 09:43:06

标签: iphone objective-c memory-management instruments

我正试图杀死iPhone 3.0应用程序中的所有内存泄漏。 CLANG建造的所有灯都是绿色的,所以现在我正在用仪器进行分析。

这说起来更容易,因为它在使用应用程序几分钟后就会显示数百个16字节的泄漏。它接缝主要在UIKit中,常见的部分是堆栈跟踪的末尾始终调用[NSObject respondsToSelector]

这是我可以忽略的东西,或者是所有这些泄漏的原因是什么? 我可以忽略它们,有没有办法在仪器中过滤它们,所以我可以检测到真正的泄漏?

*编辑 我设法找到导致问题的代码部分,但我仍然不明白为什么。 我有一个自定义UIView,其中包含一些文本和一个在异步http请求期间可见的微调器。请求完成后,我在视图上调用此方法:

- (void)fadeOut{
    spinner.hidden = YES;
    loadingLabel.hidden = YES;
    messageLabel.hidden = YES;
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationDidStopSelector:@selector(fadeComplete)];
        [UIView setAnimationDuration:0.40];
    self.alpha = 0.0;
        [UIView commitAnimations];
}

- (void)fadeComplete{
    [self removeFromSuperview];
}

如果我只是做

没有alpha动画的

[self removeFromSuperView],没有报告泄漏。

请参阅下面的屏幕截图,了解仪器详细信息。

Instruments Screenshot

示例堆栈跟踪:

   0 libobjc.A.dylib _malloc_internal
   1 libobjc.A.dylib _cache_addForwardEntry
   2 libobjc.A.dylib lookUpMethod
   3 libobjc.A.dylib class_respondsToSelector
   4 CoreFoundation -[NSObject respondsToSelector:]
   5 UIKit -[UINavigationTransitionView transition:fromView:toView:]
   6 UIKit -[UINavigationTransitionView transition:toView:]
   7 UIKit -[UINavigationController _startTransition:fromViewController:toViewController:]
   8 UIKit -[UINavigationController _startDeferredTransitionIfNeeded]
   9 UIKit -[UINavigationController viewWillLayoutSubviews]
  10 UIKit -[UILayoutContainerView layoutSubviews]
  11 UIKit -[UIView(CALayerDelegate) _layoutSublayersOfLayer:]
  12 QuartzCore -[CALayer layoutSublayers]
  13 QuartzCore CALayerLayoutIfNeeded
  14 QuartzCore CA::Context::commit_transaction(CA::Transaction*)
  15 QuartzCore CA::Transaction::commit()
  16 QuartzCore CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*)
  17 CoreFoundation __CFRunLoopDoObservers
  18 CoreFoundation CFRunLoopRunSpecific
  19 CoreFoundation CFRunLoopRunInMode
  20 GraphicsServices GSEventRunModal
  21 GraphicsServices GSEventRun
  22 UIKit -[UIApplication _run]
  23 UIKit UIApplicationMain
  24 Client main **/main.m:14
  25 Client start

还有一个:

   0 libobjc.A.dylib _malloc_internal
   1 libobjc.A.dylib _cache_addForwardEntry
   2 libobjc.A.dylib lookUpMethod
   3 libobjc.A.dylib class_respondsToSelector
   4 CoreFoundation -[NSObject respondsToSelector:]
   5 UIKit -[UIViewAnimationState animationDidStart:]
   6 QuartzCore run_animation_callbacks(double, void*)
   7 QuartzCore CA::timer_callback(__CFRunLoopTimer*, void*)
   8 CoreFoundation CFRunLoopRunSpecific
   9 CoreFoundation CFRunLoopRunInMode
  10 GraphicsServices GSEventRunModal
  11 GraphicsServices GSEventRun
  12 UIKit -[UIApplication _run]
  13 UIKit UIApplicationMain
  14 Client main ***/main.m:14
  15 Client start

2 个答案:

答案 0 :(得分:3)

您没有指定是否在实际设备上对模拟器进行了检查,但根据我在模拟器中运行Leaks的经验不太可靠,并且会报告SDK中的许多微小泄漏,同时在设备不会报告任何泄漏。

答案 1 :(得分:1)

您确定要调用您的委托方法吗?我认为问题是动画委托方法,根据Apple的文档,它必须有这个签名:

[UIView setAnimationDidStopSelector:@selector(animationFinished:finished:context:)];

然后你在班上有这样的方法:

#pragma mark -
#pragma mark UIView animation delegate method

- (void)animationFinished:(NSString *)animationID 
                 finished:(BOOL)finished 
                  context:(void *)context
{
    [self removeFromSuperview];
}

可能没有调用您的动画委托,因此,该对象不会被释放。

来自文档:

  

setAnimationDidStopSelector:

     

设置动画停止时发送给动画委托的消息。

     
      
  • (无效)setAnimationDidStopSelector:(SEL)选择
  •   
     

参数

     

选择

     

动画结束后发送给动画代表的消息。默认值为NULL。选择器应该是以下形式: - (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)完成上下文:(void *)context。您的方法必须采用以下参数:

     

animationID

     

包含可选应用程序提供的标识符的NSString。这是传递给beginAnimations:context:方法的标识符。这个论点可以是零。

     

完成   包含布尔值的NSNumber对象。如果动画在停止之前运行完成,则值为YES;如果动画没有,则返回NO。

     

上下文

     

可选的应用程序提供的上下文。这是传递给beginAnimations:context:方法的上下文数据。这个论点可以是零。

希望这有帮助!