Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 背景线程上的macOS 10.13 High:[NSGraphicsContext flushGraphics]无效_Multithreading_User Interface_Cocoa_Appkit_Macos High Sierra - Fatal编程技术网

Multithreading 背景线程上的macOS 10.13 High:[NSGraphicsContext flushGraphics]无效

Multithreading 背景线程上的macOS 10.13 High:[NSGraphicsContext flushGraphics]无效,multithreading,user-interface,cocoa,appkit,macos-high-sierra,Multithreading,User Interface,Cocoa,Appkit,Macos High Sierra,在macOS 10.12之前,以下代码在后台线程上运行良好: [nsView lockFocusFocus]; ... draw something ... [[NSGraphicsContext currentContext] flushGraphics]; [nsView unlockFocus]; 但是,对于10.13,flushGraphics不再立即更新视图的内容 我知道现在不鼓励从背景线程绘制,但这并不意味着它不再可能。事实上,一切都在。。。画点什么。。。仍然会转到视图的备份存储。

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

[nsView lockFocusFocus];
... draw something ...
[[NSGraphicsContext currentContext] flushGraphics];
[nsView unlockFocus];
但是,对于10.13,flushGraphics不再立即更新视图的内容

我知道现在不鼓励从背景线程绘制,但这并不意味着它不再可能。事实上,一切都在。。。画点什么。。。仍然会转到视图的备份存储。下一次在主UI线程上调用drawRect:后,将刷新视图,使所有内容都正确就位


如何能立即做到这一点?有没有办法使视图的更改立即可见?

事实证明,在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];
}

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

事实证明,在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];
}

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

最近macOS更新到High Sierra(可能是10.13.4)后,这个问题似乎消失了。所以flushGraphics现在确实像以前一样刷新屏幕上的更改。

最近macOS更新到High Sierra,可能是10.13.4,这个问题似乎已经消失了。所以flushGraphics现在确实像以前一样将更改刷新到屏幕上