2

我有一个 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 行文本的最佳方法是什么?像伐木工人这样的东西会是最好的解决方案吗?

4

3 回答 3

1

伐木工人非常适合伐木。此外,您应该使用 NSMutableString 来避免一次又一次地创建相同字符串的副本。

于 2013-06-30T23:55:22.553 回答
0

[self.textView.textStorage appendAttributedString: ...]

这将做更少的工作。此外,将其包装在 @autoreleasepool 中以及时清理临时对象。

于 2013-07-01T01:10:59.370 回答
-1

你应该使用这个:

NSData *data = [[NSData alloc] initWithContentsOfURL:url];

对于 300GB 的文件,这将需要一到两毫秒,并且只有在有足够的可用 RAM 时才会将整个文件加载到 RAM 中。如果没有足够的可用 RAM,它只会加载您实际读取的文件部分,并且还会以启发式/预测方式读取操作系统认为您将要读取的部分。

NSString 是 CFString 的便捷包装器。如果您下拉到较低级别的 CFString API,您将能够编写代码以使用更少的 RAM(例如,通过部分解码大文件)。从文件中部分读取字符串很复杂,您需要了解 UTF-8 的工作原理,并确保不会在 UTF-8 序列中途截断数据。如果您可以使用 NSString 获得可接受的性能,我会尽量避免使用 CFString。

另外,您是否有一个forwhile循环遍历所有文件?确保你的循环中有一个“自动释放”池:

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. */
    }
}

(来自http://developer.apple.com/library/mac/#documentation/cocoa/Conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html#//apple_ref/doc/uid/20000047-SW2

于 2013-07-01T00:43:24.737 回答