我正在我的iphone应用程序中构建一个字典数组(称为键)来保存tableview的节名和行数。
代码如下所示:
[self.results removeAllObjects];
[self.keys removeAllObjects];
NSUInteger i,j = 0;
NSString *key = [NSString string];
NSString *prevKey = [NSString string];
if ([self.allResults count] > 0)
{
prevKey = [NSString stringWithString:[[[self.allResults objectAtIndex:0] valueForKey:@"name"] substringToIndex:1]];
for (NSDictionary *theDict in self.allResults)
{
key = [NSString stringWithString:[[theDict valueForKey:@"name"] substringToIndex:1]];
if (![key isEqualToString:prevKey])
{
NSDictionary *newDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:i],@"count",
prevKey,@"section",
[NSNumber numberWithInt:j],
@"total",nil];
[self.keys addObject:newDictionary];
prevKey = [NSString stringWithString:key];
i = 1;
}
else
{
i++;
}
j++;
}
NSDictionary *newDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:i],@"count",
prevKey,@"section",
[NSNumber numberWithInt:j],
@"total",nil];
[self.keys addObject:newDictionary];
}
[self.tableview reloadData];
代码第一次运行正常,但有时我必须重建整个表,所以我重做这个代码,它在模拟器上运行得很好,但是在我的设备上程序在我执行reloadData行时发生炸弹:
malloc: *** mmap(size=3772944384) failed (error code=12)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
malloc: *** mmap(size=3772944384) failed (error code=12)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
Program received signal: “EXC_BAD_ACCESS”.
如果删除reloadData行,代码将在设备上运行。
我想知道这是否与我构建密钥数组的方式有关(即使用自动释放的字符串和字典)。
答案 0 :(得分:15)
错误消息为您提供了分配失败的明确原因:
malloc: *** mmap(size=3772944384) failed (error code=12)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
malloc: *** mmap(size=3772944384) failed (error code=12)
*** error: can't allocate region
具体来说,大小为3,772,944,384;差不多4GB。即你要求malloc()分配一些东西,导致malloc认为它需要内存映射(mmap
)近4GB的地址空间!
现在,如果您的输入字符串确实很大,那么您的代码将像davydotcom所说的那样膨胀自动释放池,但是他们必须非常真正巨大才能导致这种情况发生。如果它是那么大,那么你最终会在桌子上成千上万行或几十万行吗?如果是这样,请不要这样做 - 用户太难以使用。
如错误所示,请在malloc_error
上设置断点并发布回溯。
请注意:
NSString *key = [NSString string];
NSString *prevKey = [NSString string];
废话。
好的 - 您的代码第二眼就会表明对Objective-C guide和Cocoa memory management指南的审核会很有用。
在前四行代码中,您都泄漏了前一行并过度保留了新的self.keys
和self. self.results
(假设两者都是retain
属性,因为它们应该是这样的。
还要尝试使用Build&分析你的代码。
答案 1 :(得分:0)
如果可能的话,我强烈建议不要使用自动释放的字符串和对象,因为它们也会降低性能。代码集中的所有内容看起来都是正确的,除了顶部的奇数语句。
前两行从数组中删除所有对象,然后指定指向新self.keys和self.results的指针
只分配self.keys和self.results一次,重新加载数据时只需调用removeAllObjects。
答案 2 :(得分:0)
一个名为keys的字典数组... [self.keys addObject:newDictionary] ..需要..谎言..下来。