NSTextView setNeedsDisplay不能在Mavericks下运作?

时间:2014-01-28 03:01:44

标签: cocoa osx-mavericks nstextview setneedsdisplay

我的MacOS Cocoa应用程序显示一个静态文本窗口,这意味着它不应该被用户更改,不应该是第一响应者,等等。文本中唯一发生的事情是它的每个单词在特定时间点改变颜色(从“idleColor”变为“highlightColor”,然后再返回)。它类似于卡拉OK显示 - 单个单词改变颜色,然后根据程序控制,根据定时事件列表进行更改。

所有这些都在MacOS 10.7和10.8下运行得很好。但是,在10.9以下,文本颜色不会改变,除非我在窗口中单击并不断移动光标,因此我会连续地手动突出显示(并取消突出显示)某些文本。如果我这样做,常规单词的行为与预期一致。从本质上讲,感觉操作系统拒绝在程序控制下更新窗口,除非我通过手动执行需要UI响应的内容来强制更新窗口。

执行颜色更改的代码如下:

if (sEvent.attribute == HIGHLIGHT_ON) {
    [sTextView setTextColor:highlightColor range: currentRange];
    textIsLitUp = YES;
    }
else {
    [sTextView setTextColor:idleColor range: currentRange];
    textIsLitUp = NO;
    }
[sTextView setNeedsDisplay:YES];

(sTextView是NSTextView的子类。)

现在,如果我注释掉最后一行,那么我在10.7和10.8下会得到相同的,不正确的行为。换句话说,在10.9下,setNeedsDisplay方法不起作用,或者工作方式不同。

有没有人对解决这个问题有任何想法,或者还有其他任何解决问题的方法?或者我在做一些非常错误的事情?应用程序的关键是对textColor的更改没有延迟发生!

编辑我的问题 - 回答:

在这里找到答案!我需要在主线程上调用setNeedsDisplay - 它位于辅助线程中。奇怪的是它在10.7和10.8下似乎总能正常工作。它仅突破10.9。所以我改变了这个:

[myTextField setNeedsDisplay:YES];

对此:

dispatch_async(dispatch_get_main_queue(), ^{[myTextField setNeedsDisplay:YES];});

......它似乎有效。希望这有助于其他人...

1 个答案:

答案 0 :(得分:2)

你不想在非主线程中做任何更改AppKit对象 - 它有时会工作,甚至可能经常工作,但是每隔一段时间它就会崩溃,你会想知道为什么。所以:

[sTextView setTextColor:idleColor range: currentRange];

也需要在主线上。