【问题标题】:NSString stringWithFormat called XX times causes memory warningNSString stringWithFormat 调用 XX 次导致内存警告
【发布时间】:2012-09-15 18:00:46
【问题描述】:

我开始使用此处描述的技术监控应用内存使用情况: Programmatically retrieve memory usage on iPhone

我写了 3 个测试来尝试一下,这就是我发现的:

- (void)test1 {
for (int i = 0; i < 1000; i++) {
    NSMutableString *str = [NSMutableString stringWithString:@""];
    for (int j = 0; j < 1000; j++) {
        [str appendString:@"some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string "];
    }
}    

- (void)test2 {
for (int i = 0; i < 100000; i++) {
    @autoreleasepool {
        NSString *stri = @"";
        stri = [NSString stringWithFormat:@"%d some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really", i];
    }
}


- (void)test3 {
NSString *str = @"";
for (int i = 0; i < 500; i++) {
    str = [str stringByAppendingFormat:@"%d some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really", i];
}

当我调用 test1 或 test3 时,内存被正确分配和释放 - 我可以使用上面链接中描述的 report_memory 函数看到它。 但是当我调用 test2 时,内存并没有被释放——report_memory 不断上升。如果我多次调用 test2,我的应用会收到内存警告并被终止。

我正在使用 ARC。谁能解释一下这里发生了什么?

【问题讨论】:

  • 你在哪里使用 stringWithFormat 的结果... 比如 NSString *str =[NSString stringWithFormat:@""];
  • 那么,当你不再使用它时,为什么还要写 stringWithFormat
  • 苹果有很多文档解释了如果你在一个紧密的循环中创建了很多自动释放池,如何排空自动释放池;
  • 找到了!!!我启用了僵尸对象并忘记了它们,因此即使我使用 @autoreleasepool 块,任何分配的对象都没有被释放。

标签: iphone objective-c memory-management memory-leaks nsstring


【解决方案1】:

这是因为您在每次迭代中使用单独的自动发布实例。第一种情况,您有一个名为 str 的对象,并且您正在附加到同一个实例。这就是内存没有泄漏的原因。

尝试像这样更改调用并检查,

- (void)test2 
{
    NSString *str = @"";
    for (int i = 0; i < 100000; i++) 
    {
       str = [str stringByAppendingFormat:@"%d some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really", i];
    }
}

【讨论】:

  • 感谢您的建议 - 这确实适用于我
【解决方案2】:

stringWithFormat 返回一个自动释放的 NSString 对象。因此,在线程结束释放自动释放池时,对象将被释放。

【讨论】:

  • 1.我使用 NSTimer 更新内存使用情况,因此内存使用情况在不同的事件循环中得到更新。 2. 我使用 UIButton 多次调用 test2 - 这里也有不同的事件循环。
【解决方案3】:

成功了!!!我启用了 Zombie Objects 并忘记了它们,因此即使我使用 @autoreleasepool 块,任何分配的对象都不会被释放。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-22
    • 2011-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多