内存高效的集合类

Joe*_*Joe 3 iphone objective-c

我正在我的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];
Run Code Online (Sandbox Code Playgroud)

代码第一次工作正常,但我有时必须重建整个表,所以我重做这个在模拟器上运行良好的代码,但是在我的设备上程序在执行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”.
Run Code Online (Sandbox Code Playgroud)

如果我删除reloadData行,代码将在设备上运行.

我想知道这是否与我构建密钥数组的方式有关(即使用自动释放的字符串和字典).

bbu*_*bum 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
Run Code Online (Sandbox Code Playgroud)

具体来说,大小是3,772,944,384; 差不多4GB.即你要求malloc()分配一些东西,导致malloc认为它需要内存map(mmap)几乎4GB的地址空间!

现在,如果您的输入字符串真的很大,那么您的代码将像davydotcom所说的那样膨胀自动释放池,但它们必须真的非常巨大才能导致这种情况发生.如果它是那么大,那么你最终会在桌子上成千上万行或几十万行吗?如果是这样,请不要这样做 - 用户使用它太难了.

如错误所示,设置断点malloc_error并发布回溯.

请注意:

NSString *key = [NSString string];
NSString *prevKey = [NSString string];
Run Code Online (Sandbox Code Playgroud)

是胡说八道.

好的 - 您的代码的第二眼可以看出对Objective-C指南Cocoa内存管理指南的审查会很有用.

在前四行代码中,你们都泄漏了前一行并且过度保留了new self.keysself. self.results(假设两者都是retain属性,因为它们应该是).

还可以尝试在代码中使用Build&Analyze.