我有一个NSTextView,我正在将其作为控制台。要记录内容,我使用以下方法:
- (void)log:(NSString *)logString
{
NSDateFormatter* formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
NSString* dateTime = [formatter stringFromDate:[NSDate date]];
[[self consoleText] setString:[NSString stringWithFormat:@"%@\n[%@]: %@", [self consoleText].string, dateTime, logString]];
}
此方法很有效,直到日志窗口变满。一旦滚动条出现,日志功能就会导致程序挂起。为什么呢?
我添加了一些日志记录,发现导致程序挂起的确切行是:
[[self consoleText] setString:[NSString stringWithFormat:@"%@\n[%@]: %@", [self consoleText].string, dateTime, logString]];
特定问题来自于setString:
方法本身。如果我将stringWithFormat:
分开并声明字符串以预先设置它,它仍会挂起:
[[self consoleText] setString:outputString];
但仅当内容足够大才能产生滚动条时。
答案 0 :(得分:0)
这里真正的问题是这个方法是从后台线程调用的。 AppKit在后台线程中不安全,因此您应该从主线程调用所有UI更新。将setString:
置于主队列异步调度中可以解决问题:
dispatch_async(dispatch_get_main_queue(), ^(void){
[[self consoleText] setString:outputString];
});
非常奇怪,直到需要出现滚动条才能正常工作......