【发布时间】:2011-05-26 02:16:04
【问题描述】:
我的应用在 3G iPhone 上以约 23mb 的速度关闭。
我正在将一个 3mb 文件加载到 NSArray 中,如下所示... str 和 lines 不会自动释放吗?关于更好的方法来做到这一点的任何建议?
NSString *str = [NSString stringWithContentsOfFile:path
encoding:NSUTF8StringEncoding error:&error];
NSArray *lines = [str componentsSeparatedByString: @"\n"];
[self parseDictLines:lines];
- (void)parseDictLines:(NSArray *)lines {
int i = 0;
NSMutableArray *arr = [[[NSMutableArray alloc] init] autorelease];
NSMutableArray *word_list = [[NSMutableArray alloc] init];
for (NSString *line in lines) {
i++;
[arr addObject:line];
if ( i == 3 ) {
i = 0;
[word_list addObject:[arr copy]];
[arr removeAllObjects];
}
}
self.mDict = (NSArray*)word_list;
[word_list release];
}
编辑 - 该应用程序在此代码之前小于 1mb,或者如果我跳过此代码。运行后它是 22mb ......所以它不能是临时变量......它可以使用,直到我做一些增加另一个 1mb 的事情,此时它会保释。
EDIT2 - 文件的 NSString *str 为 5.9mb - 由于字符串在内存中的编码方式,我假设它是 UTF8 文件的两倍。 *lines 数组也是这个大小。
然而,直到我添加了自动释放池,str 才被立即释放。使用仪器运行时,NSArray *lines 需要 5 分钟才能填满,在调用 [lines release] 之后,在内存开始消失之前大约需要 3 分钟,然后在 *lines 数组使用的内存关闭之前需要 5 分钟
下面的代码解决了我的问题,这显然是我在 str 和 lines 内存被释放之前达到了内存限制。现在 str 立即被释放,释放了 6mb,并且在后台加载此代码时,用户现在不可能超过限制。
但是 - 为什么当我已经自动释放 12mb 时操作系统会转储我的应用程序?它不会清理任何需要自行自动发布的东西吗?
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSString *str = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error];
NSArray *lines = [[str componentsSeparatedByString: @"\n"] retain];
[pool drain];
[self parseDictLines:lines];
[lines release];
【问题讨论】:
-
也许不会一次加载整个数组:而是按需加载(分页或单个条目或诸如此类)。这将需要更多的前期设计,并且可能并不总是适用。也许它可能会更好地存储在二叉树或堆中,或者使用其他存储机制。
-
如果文件是 3mb,我不得不想象什么基本上是一个 NSArray 的行不能超过 3mb ......我一定是在上面的代码中犯了一个错误。我可能可以将其子集化,然后从我们将看到的文件中按需加载其余部分。我不想发疯,因为我是 ObjectiveC 的新手
-
在您的应用程序上运行
instruments,看看您是否可以识别内存泄漏,这是一个很棒的工具 -
你的文件有多少行?任何 unicode 字符?
-
当你说应用在这段代码之前