2010-05-08 141 views
2

我再一次在我的代码中寻找内存泄漏和其他疯狂的错误。 :)iPhone:内存不足崩溃

我有一个经常使用的文件(图像,数据记录等TTL约为一周,大小有限的缓存(100MB))的缓存。 目录中的文件有时多于15000个。在应用程序退出时,缓存将写入一个包含当前缓存大小的控制文件以及其他有用的信息。如果应用程序由于某种原因崩溃 (sh ..有时会发生)我在这种情况下计算应用程序启动时所有文件的大小,以确保知道缓存大小。 由于内存不足,我的应用崩溃了,我不知道为什么。

内存泄漏检测器根本不显示任何泄漏。我也没有看到。有什么问题 与下面的代码?有没有其他快速的方法来计算在iPhone上的目录内的所有文件的总大小 ?也许没有列举目录的全部内容?代码在主线程上执行。

NSUInteger result = 0; 
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
NSDirectoryEnumerator *dirEnum = [[[NSFileManager defaultManager] enumeratorAtPath:path] retain]; 
int i = 0; 
while ([dirEnum nextObject]) { 
    NSDictionary *attributes = [dirEnum fileAttributes]; 
    NSNumber* fileSize = [attributes objectForKey:NSFileSize]; 
    result += [fileSize unsignedIntValue]; 

    if (++i % 500 == 0) { // I tried lower values too 
     [pool drain]; 
    } 
} 
[dirEnum release]; 
dirEnum = nil; 
[pool release]; 
pool = nil; 

感谢, MacTouch

回答

5

排水池 “释放” 它,它不只是空的。将autorelease池想象成堆栈,所以你已经弹出了你的意思,这意味着所有这些新对象都会进入主autorelease池,并且在被弹出之前不会被清理。相反,将您的autorelease池的创建移动到循环内部。你可以做点像

NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; 
int i = 0; 
while(shouldloop) { 
    // do stuff 
    if(++i%500 == 0) { 
    [pool drain]; 
    pool = [[NSAutoreleasePool alloc] init]; 
    } 
} 
[pool drain]; 
+0

谢谢。嘘..我真的不知道。我一直在想流失只是为所有自动释放的对象免费提供momory。 这是一个RTFM的经典案例。 :-) 谢谢。现在我必须确保我在所有使用Autoreleasepool的地方都以相同的方式进行操作。 Uff ...有很多。 :) – MacTouch 2010-05-08 15:50:52

+0

MacTouch:阅读NSAutoReleasePool的文档 - 可可和Cocoa-touch之间的行为存在重要差异。 – Olie 2010-06-16 19:30:53

+0

看起来像“池”在代码中泄漏。 – tmin 2011-02-10 00:42:09

相关问题