为什么静态NSString泄漏?

问题描述

| 我有以下代码来检索我的iOS应用上的文件路径:
static const Nsstring * fullPathFromrelativePath(Nsstring *relPath)
{
    // do not convert a path starting with \'/\'
    if(([relPath length] > 0) && ([relPath characteratIndex:0] == \'/\'))
        return relPath;

    NSMutableArray *imagePathComponents = [NSMutableArray arrayWithArray:[relPath pathComponents]];

    Nsstring *file = [imagePathComponents lastObject];    
    [imagePathComponents removeLastObject];

    Nsstring *imageDirectory = [Nsstring pathWithComponents:imagePathComponents];

    Nsstring *fullpath = [[NSBundle mainBundle] pathForResource:file
                                                         ofType:NULL
                                                    inDirectory:imageDirectory];
    if (!fullpath)
        fullpath = relPath;

    return fullpath;    
}

static const char * fullCPathFromrelativePath(const char *cPath)
{
    Nsstring *relPath = [Nsstring stringWithCString:cPath encoding:NSUTF8StringEncoding];
    const  Nsstring *path = fullPathFromrelativePath(relPath);
    const char *c_path = [path UTF8String];
    return c_path;
}

static const char * relativeCPathForFile(const char *fileName)
{        
    Nsstring *relPath = [Nsstring stringWithCString:fileName encoding:NSUTF8StringEncoding];        
    const Nsstring *path = fullPathFromrelativePath(relPath);
    const char *c_path = [[path stringByDeletingLastPathComponent] UTF8String];    
    return c_path;
}
我在调试控制台中收到了很多这样的消息:
objc[4501]: Object 0x6e17060 of class __NSCFString autoreleased with no pool in place - just leaking - break on objc_autoreleasenopool() to debug
objc[4501]: Object 0x6e12470 of class NSPathStore2 autoreleased with no pool in place - just leaking - break on objc_autoreleasenopool() to debug
objc[4501]: Object 0x6e12580 of class __NSCFData autoreleased with no pool in place - just leaking - break on objc_autoreleasenopool() to debug
代码有什么问题? (我什至在使用带有“自动”保留/释放功能的iOS 5等) 干杯。     

解决方法

        当您自动释放其堆栈中没有任何释放池的线程上的对象时,将显示此消息。默认情况下,主线程上始终有一个自动释放池。它是在通常由应用程序的main()函数调用的
UIApplicationMain()
函数中创建和管理的。但是,您创建的其他线程(使用
performSelectorInBackground:
NSThread
)没有适当的自动释放池,除非您专门在其中放置了一个自动释放池,因此该后台线程上的任何自动释放的对象都没有池供以后释放它们,只会泄漏。 如果您要启动后台线程,那么您应该做的第一件事就是创建一个自动释放池。在ARC下,使用新的“ 5”结构进行操作。     ,        您是否尝试过在非ARC应用程序中运行相同的代码?您可以通过这样做来确认这是ARC问题还是框架中的实际错误。 ARC仍不成熟,Apple已多次声明尚未完成,并且肯定存在错误。 如果您担心要创建的明显的自动释放对象的数量,请在有问题的代码周围使用“ 6”构造。它比您始终无法在ARC代码中创建的NSAutoreleasePool效率要高得多。     ,        我认为那不是真正的泄漏。苹果已经在模拟器上讨论了几次,这是模拟器库如何处理NSAutoReleasePool的一个已知的伪错误,但不足以保证修复,因为您的Mac内存比设备大得多。在WWDC上,他们提到了NSZombie在某些地方无法正确处理自动释放,但我不记得当时正在进行的会话。除非您注意到Instruments中这些对象的泄漏,否则您不应该\不用担心。如果您确实注意到使用仪器泄漏,请提交错误报告。 不要仅仅因为它看起来可能正在泄漏而在您的方法周围创建一个自动释放池。在ARC上无论如何都无法正常工作,除非您已修改应用程序的main()函数,否则您将拥有一个自动发布池,其中包含了所有内容。创建一个额外的自动释放池而不分析数据表明在调用该方法后您的内存严重不足,实际上会使您的应用程序性能下降。     ,        如果您已删除main.m文件中的NSAutoreleasePool调用,或者此代码正在单独的线程中执行,则会发生这种情况。 因为您不能将NSAutoreleasePool与ARC一起使用,所以必须将线程代码放在@autoreleasepool块中