为什么静态NSString泄漏?
我有以下代码来检索我的iOS应用程序的文件path:
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; }
在debugging控制台中,我收到了很多这样的消息:
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自动保留/释放等)
干杯。
当您在堆栈中没有任何发布池的线程上自动释放对象时,会显示此消息。 默认情况下,主线程上总是有一个自动释放池。 它在UIApplicationMain()
函数中创build和pipe理,通常由您的应用程序的main()函数调用。 但是,创build的其他线程(使用performSelectorInBackground:
或NSThread
)没有适当的自动释放池,除非您特别在其中放置一个线程,所以后台线程上的任何自动释放对象都没有池,以后才会释放它们,只会泄漏。
如果你正在踢背景线,你应该做的第一件事就是创build一个自动释放池。 在ARC下,使用新的@autoreleasepool
构造来做到这一点。
您是否曾尝试在非ARC应用程序中运行相同的代码? 你可以通过这个确认是否是ARC问题或者是框架中的一个真正的bug。 ARC还不成熟,苹果已经多次表示它还没有完成,肯定有缺陷。
如果您担心正在创build的显式autorelease对象的数量,请使用围绕相关代码的@autoreleasepool {...}
构造。 它比NSAutoreleasePool 更有效率 ,无论如何你都不能在ARC代码中创build它。
我不认为这是真正的泄漏。 苹果已经讨论了几次,在模拟器上它是模拟器库处理NSAutoReleasePool的一个已知的伪错误,但是不足以保证修复,因为你的MAC比设备有更多的内存。 在WWDC上,他们提到NSZombie没有正确处理autorelease,但是我不记得是在什么会话中。除非你注意到Instruments中的这些对象泄漏,否则你不应该担心它。 如果您发现泄漏使用仪器,请提交错误报告。
不要在你的方法周围创build一个Autorelease Pool,因为它看起来可能会泄漏。 在ARC上无法正常工作,除非你修改了你的应用程序的main()函数,否则你的autorelease池就包装了所有东西 。 创build一个额外的自动释放池而不分析数据,表明在调用该方法后存在严重的内存压力,这实际上会使应用程序性能变差。
如果您已经在main.m文件中删除了NSAutoreleasePool调用,或者这个代码正在独立线程中执行,就会发生这种情况。 因为你不能在ARC中使用NSAutoreleasePool,你必须把线程代码放在@autoreleasepool块中