Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to update UI in a task completion block?

In my application, I let a progress indicator starts animation before I send a HTTP request. The completion handler is defined in a block. After I get the response data, I hide the progress indicator from inside the block. My question is, as I know, UI updates must be performed in the main thread. How can I make sure it?

If I define a method in the window controller which updates UI, and let the block calls the method instead of updating UI directly, is it a solution?

like image 789
Stephen Hsu Avatar asked Dec 28 '22 15:12

Stephen Hsu


1 Answers

Also, if your app targets iOS >= 4 you can use Grand Central Dispatch:

dispatch_async(dispatch_get_main_queue(), ^{
    // This block will be executed asynchronously on the main thread.
});

This is useful when your custom logic cannot easily be expressed with the single selector and object arguments that the performSelect… methods take.

To execute a block synchronously, use dispatch_sync() – but make sure you’re not currently executing on the main queue or GCD will deadlock.

__block NSInteger alertResult; // The __block modifier makes alertResult writable
                               // from a referencing block.
void (^ getResponse)() = ^{
    NSAlert *alert = …;
    alertResult = [NSAlert runModal];
};

if ([NSThread isMainThread]) {
    // We're currently executing on the main thread.
    // We can execute the block directly.
    getResponse();
} else {
    dispatch_sync(dispatch_get_main_queue(), getResponse);
}

// Check the user response.
if (alertResult == …) {
    …
}
like image 51
gcbrueckmann Avatar answered Feb 23 '23 11:02

gcbrueckmann