Как правильно отображать лист «хода выполнения» в модальном режиме при использовании Grand Central Dispatch для обработки чего-либо?

Я пытаюсь отобразить лист в окне, содержащем одну полосу выполнения, чтобы показать прогресс какой-то длинной функции, выполняющейся асинхронно с использованием Grand Central Dispatch. Я почти получил его, но не могу заставить лист казаться в фокусе, вероятно, потому, что я не использовал runModalForWindow: или аналогичный.

Это примерно то, что я делаю сейчас, это происходит в результате нажатия кнопки в главном окне:

    // Prepare sheet and show it...

    [NSApp beginSheet:progressSheet modalForWindow:window modalDelegate:nil didEndSelector:NULL contextInfo:NULL];

    [progressSheet makeKeyAndOrderFront:self];

    [progressBar setIndeterminate:NO];
    [progressBar setDoubleValue:0.f];
    [progressBar startAnimation:self];


    // Start computation using GCD...

    dispatch_async(dispatch_get_global_queue(0, 0), ^{

        for (int i = 0; i < 1000; i ++) {
            // Do some large computation here
            // ...

            // Update the progress bar which is in the sheet:
            dispatch_async(dispatch_get_main_queue(), ^{
                [progressBar setDoubleValue:(double)i];
            });
        }


        // Calculation finished, remove sheet on main thread

        dispatch_async(dispatch_get_main_queue(), ^{
            [progressBar setIndeterminate:YES];

            [NSApp endSheet:progressSheet];
            [progressSheet orderOut:self];
        });
    });

Это работает, за исключением того, что главное окно все еще в фокусе, лист не в фокусе , и индикатор выполнения не анимируется (если я не использую для него setUsesThreadedAnimation: YES ).

Проблема, с которой я столкнулся, заключается в том, что я не знаю, как запустить лист модально, не блокируя основной поток, прежде чем я начну асинхронное вычисление?

11
задан Robert 8 November 2011 в 16:59
поделиться