我有一个Cocoa程序正在编辑数百个(有时是数千个)第三方文件,我想创建一个日志类型的输出供最终用户查看(虽然我不需要像时间戳这样的东西)。目前我只是将字符串附加到插座:
@property (unsafe_unretained) IBOutlet NSTextView *finalText;
...
self.finalText.string = [self.finalText.string stringByAppendingFormat:@"Final results:\n"];
但效率极低。当我在700个文件上运行该代码并关闭上述代码(所有注释)时,执行上述代码需要4秒钟,上面的代码打开需要40秒才能创建必要的8,000行输出。哦,我是否提到Xcode说我的内存使用量在处理过程中达到了2GB以上?糟糕!
我明白我所做的事情效率低下,但我不知道提高效率的最佳方法。创建最终用户最终可以看到的8,000行文本的最佳方法是什么?像Lumberjack之类的东西会是最好的解决方案吗?
答案 0 :(得分:1)
伐木工人非常适合伐木。此外,您应该使用NSMutableString来避免一次又一次地创建相同字符串的副本。
答案 1 :(得分:0)
[self.textView.textStorage appendAttributedString:...]
这将减少工作量。另外,将其包装在@autoreleasepool中以及时清理临时对象。
答案 2 :(得分:-1)
你应该用这个:
NSData *data = [[NSData alloc] initWithContentsOfURL:url];
使用300GB文件需要一到两毫秒,如果有足够的RAM可用,只会将整个文件加载到RAM中。如果没有足够的RAM可用,它将仅加载您实际读取的文件的部分,并且还可以启发式/预测性地读取操作系统认为您将要阅读的部分。
NSString是CFString的便利包装器。如果您下拉到较低级别的CFString API,您将能够编写代码,以便它使用较少的RAM(例如,通过部分解码大文件)。从文件中部分读取字符串很复杂,您需要了解UTF-8的工作原理,并确保不要在UTF-8序列的中途剪切数据。如果你能用NSString获得可接受的性能,我会尽量避免使用CFString。
此外,您是否有for
或while
循环遍历所有文件?确保循环中有一个“autorelease”池:
NSArray *urls = <# An array of file URLs #>;
for (NSURL *url in urls) {
@autoreleasepool {
NSError *error;
NSString *fileContents = [NSString stringWithContentsOfURL:url
encoding:NSUTF8StringEncoding error:&error];
/* Process the string, creating and autoreleasing more objects. */
}
}