【发布时间】:2013-03-18 10:35:06
【问题描述】:
在我正在开发的应用程序中,我在 for 循环中从文本文件中读取数值,然后进行一些计算并将结果附加到结果字符串中。
该文件中有 22050 个值。我注意到,超过一定数量的附加循环/值(~5300)它往往会崩溃。
我想也许我有内存泄漏,所以我去掉了附加的字符串,一切正常。我试图摆脱所有东西,但附加的字符串和应用程序崩溃了。我在所有异常上都有一个断点,我没有得到任何异常。
我想确定一下,所以我开始了一个新项目。我只放了一个 UIButton,当它被推送时会调用这段代码:
- (IBAction)TestPressed:(id)sender
{
NSString *testString = @"";
for (int i = 0; i < 22050; i++)
{
testString = [testString stringByAppendingString:@"12.34567890\n"];
}
NSLog(@"%@", testString);
}
我在 NSLog 行上有一个断点。该应用程序之前崩溃。
NSString 长度有限制吗?会不会占用太多内存?
【问题讨论】:
-
如果你使用一个可变的字符串,会有什么不同吗?
NSMutableString *testString = [NSMutableString string];和[testString appendString:@"12.34567890|n"]; -
您使用的是 iOS 还是 MacOS?如果您使用 iOS 并使用
stringByAppendingString而您没有使用 ARC,那么您就像筛子一样泄漏内存。如果您使用的是 ARC,那么至少它应该为新字符串释放旧字符串。 @Fogmeister 的建议也应该改进,不管 ARC。 -
@gaige 在这种情况下,Mac/iOS 和 ARC/MRC 之间没有区别。临时字符串只是进入自动释放池。
-
@NikolaiRuhe 我不相信这是真的。对于 ARC,分配本地拥有的变量通常会在分配后导致释放,因为 ARC 知道它是唯一的所有者。我刚刚编译了这个确切的代码并查看了反汇编代码,它调用的是
-release,而不是-autorelease -
@gaige 问题是
stringByAppendingString:返回一个自动释放的对象。所以 ARC 不能神奇地从池中移除对象。如果stringByAppendingString:也使用 ARC 编译(我不知道),这将起作用的唯一方法。然后stringByAppendingString:中的代码可以决定省略自动释放,因为它知道接收代码正确处理内存管理。但这没有记录在案,任何推测对于 MacOS 和 iOS 应该是相同的。
标签: objective-c crash nsstring