1

在 macOS 10.12 之前,以下代码在后台线程上运行良好:

[nsView lockFocusFocus];
... draw something ...
[[NSGraphicsContext currentContext] flushGraphics];
[nsView unlockFocus];

然而,在 10.13 中,flushGraphics 不再立即更新视图的内容。

我知道现在不鼓励从后台线程进行绘图,但这并不意味着它不再可能。事实上,...中的所有内容...绘制一些东西...仍然进入视图的后备存储。一旦 drawRect: 下一次在主 UI 线程上被调用,视图就会刷新,所有内容都正确到位。

如何让这立即发生?有没有办法让视图的更改立即可见?

4

2 回答 2

0

事实证明,在 macOS 10.13 中,如果drawRect:实际上没有在该方法的范围内绘制任何内容,那么即使修改了其后备存储,视图的显示也不会刷新。

因此,如果你想刷新屏幕上的未决更改,诀窍是通过至少绘制一个小的不可见矩形来让 AppKit认为已经绘制了一些东西:

- (void) drawRect: (NSRect)rect
{
    if (drawRectWasRequestedByRefresh) {
       // flush pending changes drawn on background thread
       [[NSColor clearColor] set];
       [NSBezierPath strokeRect: NSMakeRect(0,0,1,1)];
       drawRectWasRequestedByRefresh = NO;
    } else {
       // draw your view's regular contents here
    }
}

要从后台线程触发刷新,请使用以下技巧:

- (void) refresh
{
    drawRectWasRequestedByRefresh = YES;
    [self setNeedsDisplay: YES];
}

这当然是一个肮脏的黑客,只有需要从后台线程立即绘制(无论出于何种原因)的应用程序才需要。如果有人知道更好的解决方案,我会很高兴听到它!

于 2017-10-29T22:33:39.960 回答
0

看来,随着最近对 High Sierra 的 macOS 更新,可能是 10.13.4,这个问题已经消失了。因此,flushGraphics 现在确实像以前一样将更改刷新到屏幕。

于 2018-04-23T10:38:36.867 回答