繁体   English   中英

在非主线程中运行Cocoa GUI

[英]Running a Cocoa GUI in a non-main thread

我在开发cocoa用户界面时遇到了与gui / threading相关的问题。 该应用程序的设计如下:

主线程(#1):解析参数,加载插件等。

Gui线程(#?):启动gui,处理事件等。它是gui线程。

Cocoa框架是非线程安全的,但是强制执行一条规则,GUI必须在主线程上运行。 断言用于检查这一点。 为了解决这个问题,我自己实现了run方法(下面的代码) - http://cocoawithlove.com/2009/01/demystifying-nsapplication-by.html - guide。 但我错过了一些东西。 窗口打开,但保持空白(完全白色)。 虽然如果我在主线程中进行调用,它可以完美地工作。

所以基本上我需要弄清楚缺少什么。

- (void)run
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    [self finishLaunching];

    shouldKeepRunning = YES;
    do
    {
        [pool release];
        pool = [[NSAutoreleasePool alloc] init];

        NSEvent *event =
            [self
                nextEventMatchingMask:NSAnyEventMask
                untilDate:[NSDate distantFuture]
                inMode:NSDefaultRunLoopMode
                dequeue:YES];

        [self sendEvent:event];
        [self updateWindows];
    } while (shouldKeepRunning);

    [pool release];
}

- (void)terminate:(id)sender
{
    shouldKeepRunning = NO;
}

别。 这种方法永远不会奏效。 即使您修复了当前的问题(窗口没有绘制),您也会立即遇到另一个模糊的,不可能解决的问题,另一个问题,另一个问题。 Cocoa期望GUI线程成为主线程,故事结束。

为什么不扭转这个问题呢? 让主线程产生一个线程(让我们称之为app线程),然后在产生GUI之前阻塞。 应用程序线程将解析参数,加载插件等。初始化完成后,应用程序线程将通知主线程继续并启动GUI。

除了更新GUI之外,在后台线程中执行所有操作。 我看到你只有一行需要更新GUI。 所以按照你的方式去做,除了你在主线程中执行所有GUI更新:

dispatch_async(dispatch_get_main_queue(), ^
{
    [self updateWindows];
});

现在我不知道什么是updateWindows,我认为这不会造成竞争条件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM