13

I'm using Objective-C blocks and Operation Queues for the first time. I'm loading some remote data while the main UI shows a spinner. I'm using a completion block to tell the table to reload its data. As the documentation mentions, the completion block does not run on the main thread, so the table reloads the data but doesn't repaint the view until you do something on the main thread like drag the table.

The solution I'm using now is a dispatch queue, is this the "best" way to refresh the UI from a completion block?

    // define our block that will execute when the task is finished
    void (^jobFinished)(void) = ^{
        // We need the view to be reloaded by the main thread
        dispatch_async(dispatch_get_main_queue(),^{
            [self.tableView reloadData];
        });
    };

    // create the async job
    NSBlockOperation *job = [NSBlockOperation blockOperationWithBlock:getTasks];
    [job setCompletionBlock:jobFinished];

    // put it in the queue for execution
    [_jobQueue addOperation:job];

Update Per @gcamp's suggestion, the completion block now uses the main operation queue instead of GCD:

// define our block that will execute when the task is finished
void (^jobFinished)(void) = ^{
    // We need the view to be reloaded by the main thread
    [[NSOperationQueue mainQueue] addOperationWithBlock:^{ [self.tableView reloadData]; }];
};
Jeremy Mullin
  • 4,170
  • 4
  • 36
  • 54

1 Answers1

18

That's exactly it. You can also use [NSOperationQueue mainQueue] if you want to use an operation queue instead of GCD for your completion block.

gcamp
  • 14,622
  • 4
  • 54
  • 85
  • Cool, I didn't know about mainQueue. A little cleaner and more consistent that way. Thanks! – Jeremy Mullin May 24 '11 at 16:13
  • Is there an actual difference between using [NSOperationQueue mainQueue] and dispatch_get_main_queue()? – Greg Maletic Jun 08 '11 at 00:03
  • 1
    In matter of result, no. But it's different in how you use it. `NSOperationQueue` uses (obviously) `NSOperation`and GCD (dispatch_get_main_queue) uses block. – gcamp Jun 08 '11 at 01:54
  • @gcamp But NSOperation/Queue is implemented with GCD, so it's the smae thing either way, no? – 0xSina Jan 13 '13 at 22:36
  • @0xSina The end result is the same, yes, but the API is different. That's exactly what I said in my previous comment. – gcamp Jan 15 '13 at 17:25
  • Debugged the whole day to find out that my completion called through OperationQueue.main inside a block operation was not calling the completion and that changing it to Dispatch.async was the fix. – Fawkes Jun 06 '18 at 15:34