Objective c 调度同步(调度获取主队列()UI异常

Objective c 调度同步(调度获取主队列()UI异常,objective-c,macos,cocoa,objective-c-blocks,grand-central-dispatch,Objective C,Macos,Cocoa,Objective C Blocks,Grand Central Dispatch,这是针对MacOS而不是iOS的 如果您在GCD队列上运行代码 dispatch_sync(dispatch_get_main_queue(), ^{ //do UI stuff }); 这几乎是在主线程/队列上完成UI工作的方法,对于iOS来说似乎效果不错。 MacOS似乎是另一回事。 试试这个简单的例子 - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { dispatch_async

这是针对MacOS而不是iOS的

如果您在GCD队列上运行代码

dispatch_sync(dispatch_get_main_queue(), ^{
    //do UI stuff
});
这几乎是在主线程/队列上完成UI工作的方法,对于iOS来说似乎效果不错。 MacOS似乎是另一回事。 试试这个简单的例子

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        // So my app is doing some background stuff
        // and I need a file from the user so

        // code blah blah code

        dispatch_sync(dispatch_get_main_queue(), ^{
            NSOpenPanel *op = [NSOpenPanel openPanel];

            [op runModal];
        });

        // resume code blah blah code
    });
}
当NSOpenPanel打开时,会出现各种奇怪的情况。滚动视图滚动非常不稳定(如果有的话),并且目录列表不正确。我只是以NSOpenPanel为例,任何包含滚动视图的视图都会出现这种情况(到目前为止我已经测试过了)。 这是虫子吗?
其他人看到了吗?还是只有我一个人看到了?还有其他更可取的方法吗?

问题是您正在阻止主线程,因为主线程是串行调度队列。主线程无法运行,因为它在
runModal
方法中被阻止

在讨论之后,解决方案是使用
beginWithCompletionHandler:
,我已经验证了这一点:

//[op runModal];
[op beginWithCompletionHandler:^(NSInteger result) {
    NSLog(@"Done: %lu", (unsigned long)result);
}];
dispatch\u sync(dispatch\u get\u main\u queue(),…)
绝对不是执行UI操作的“方法”——它实际上是一个巨大的潜在问题;这里的详细信息:当从全局后台队列向主线程分派时,您希望使用
dispatch\u async
。如果您需要继续行为(也就是说,后台任务的剩余部分要等到UI更新完成后)您应该找到另一种方法。从主线程块的末尾返回后台线程的
dispatch\u async
是最明显的方法,但是
dispatch\u group\u notify
是另一种方法,等等)。