4

I am calling the following Class method from within my ViewController init method:

[NSURLConnection sendAsynchronousRequest:urlrequest 
                                   queue:opQueue 
                       completionHandler:^(NSURLResponse *response, NSData *data, NSError*error){


// Update an NSMutableArray (an Instance variable

[self tableView] reloadData]; // is this ok to call?
}];

This code working as intended and tableView refreshes appropriately, My concern: is this call thread safe?. is it ok to access an UI element from the completion block?

Thanks,

Vinod

Vinod
  • 93
  • 5

2 Answers2

8

Actually, this is not correct unless opQueue happens to be +[NSOperationQueue mainQueue]

That completion block will be scheduled on the queue you provide. In your case, you're calling that queue 'opQueue'. If that queue is being drained by some thread other than the main thread, then you shouldn't make that call to reload the tableview there.

You should instead do whatever processing you need to do and then enqueue another block on the main queue which calls the reload.

^(NSURLResponse *response, NSData *data, NSError*error){

   // Do some processing work in your completion block

   dispatch_async(dispatch_get_main_queue(), ^{

    // Back on the main thread, ask the tableview to reload itself.
    [someTableView reloadData];

   });
}

Or if the processing is light and quick (and fixed amount of time), then just pass the mainQueue as the 'opQueue';

I hope that makes sense. A lot of good information to be found here: Concurrency Programming Guide

Firoze Lafeer
  • 17,133
  • 4
  • 54
  • 48
  • Firoze, Could you direct me to some documentation on this?. In this case then calling dispatch_get_main_queue() from within the completion block in appropriate? – Vinod Dec 09 '11 at 20:10
  • Vinod, yes you can get the main GCD queue that way. That would work fine. On which point would you like documentation? – Firoze Lafeer Dec 09 '11 at 21:40
1

It is thread safe. Very much because you are not using threads. The completion handler is just called later, not on a separate thread.

fearmint
  • 5,276
  • 2
  • 33
  • 45
  • 1
    From my experience with the blocked based methods in Apple's frameworks, they never make guarantees about what thread a completion handler will run on. It's up to you to ensure that UI code is only executed on the main thread. – Mark Adams Dec 10 '11 at 00:10
  • Oh I hadn't thought of that. That's an important distinction to make. – fearmint Dec 10 '11 at 00:18
  • Just as Firoze recommended, I am using dispatch_get_main_queue() and it is working fine. Agree, It seems that documentation is spotty at the best when it comes to block based methods. – Vinod Dec 10 '11 at 03:10