使用Instruments Leaks&对象分配:自动释放的对象是否被视为泄漏?

时间:2009-03-23 18:48:03

标签: objective-c iphone cocoa-touch memory-leaks instruments

我有一个iPhone应用程序正在获取内存警告,所以我试图在Instruments的帮助下找到泄漏,更有效地使用内存等。除此之外,我正在尝试取出任何自动释放的对象并替换为手动alloc / init / release对象。但是,某些API调用似乎没有“init”版本(请参阅下面的代码)。我承认有一些基本的误解:

  1. 如果我'调用'API并返回基本上自动释放的对象,那么这些对象是否会在仪器中显示为泄漏?我似乎在仪器中看到了这种行为。

  2. 如果是2,我是否应该忽略是否有'非自动释放'替代方案并且我正在使用我需要的API?另外,如果这个代码被大量调用,我是否应该重新考虑algor?

  3. 这是我的应用程序中的一些实用程序代码,它被调用很多。基本上确定两个日期是否有意义“相等”。我已经留下了已注释掉的代码,因此您可以在我的代码库中看到我正在进行的改进类型 - 当我开始手动创建时,此DID会减少随后在“工具”中运行时的内存泄漏 NSDate(和发布)有所帮助。但是,我仍然有我认为泄漏的日期组件对象...但它是一个API调用(对于代码格式化很抱歉,但我似乎无法在SO上改进它):

    + (BOOL)isDayEqualToDay:(NSDate*)date anotherDate:(NSDate*)anotherDate
    {
    
        NSCalendar *cal = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];  
        //NSCalendar *cal;  
        NSDateComponents *componentsFromDate, *componentsFromAnotherDate;   
        NSUInteger unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit;    
        //cal = [NSCalendar currentCalendar];
        componentsFromDate = [cal components:unitFlags fromDate:date];
        componentsFromAnotherDate = [cal components:unitFlags fromDate:anotherDate];
    
        BOOL bDatesEqual = ([componentsFromDate year] == [componentsFromAnotherDate year] && 
                            [componentsFromDate month] == [componentsFromAnotherDate month] && 
                            [componentsFromDate day] == [componentsFromAnotherDate day]);
    
        [cal release];
    
        return bDatesEqual;
    
        /*
        return (
            [componentsFromDate year] == [componentsFromAnotherDate year] &&
            [componentsFromDate month] == [componentsFromAnotherDate month] && 
            [componentsFromDate day] == [componentsFromAnotherDate day]
        );*/
    }
    

    我认为componentsFromDate和componentsFromAnotherDate显示为泄漏,但只有从NSData API调用(自动释放)返回的对象。不知道我还能做些什么来提高效率,而且我质疑我对如何最好地使用乐器的理解。建议

2 个答案:

答案 0 :(得分:4)

自动释放的对象不应该显示为内存泄漏。有时API会在内部泄漏内存。您应该向Apple提交错误报告。像NSCalendar和NSDateComponenets这样的新类尤其令人怀疑。

至于保留与自动释放,一般规则是除非你处于紧密循环中并不重要。在这种情况下,如果紧密循环在没有事件发生的情况下进行了数千次,则意味着您永远不会“清理”自动释放池。

答案 1 :(得分:3)

当使用像GCD之类的东西时,有一个自动释放池,但你无法知道何时(如果有的话)默认的自动释放池被耗尽。如果您确信释放的对象没有释放,请确保您了解正在使用的线程API。如果内存为我提供正确的GCD调用(dispatch_async)为您排序自动释放池,但实际耗尽池可能需要很长时间。另一方面,NSOperations允许您拥有自动释放池。

我已经看到仪器中的内存泄漏检测依赖于10秒的间隔会导致错误的内存泄漏警告,因为在自动释放池耗尽之前会延迟一段时间。因此,请尝试将有问题的代码包装在:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
... [your code] ...
[pool drain];

我建议不要尝试用手动版本替换所有自动释放。使用自动释放会在一个位置产生平衡的保留/释放呼叫计数。在我看来,创建一个对象然后立即自动释放它可以防止大量的内存错误。快速,简单。在使用手动释放呼叫时,您将忘记释放内容。进行手动释放时,特别是错误条件很棘手。

自己做一个池可以让你获得更多控制权,在分配密集型工作期间,创建和排空自己的池有时会更有帮助。但是一如既往地尝试和测试,不做任何假设。