Table view updates from NSNotification posts

My app has a tableview with cells that can each call for a download of content to a singleton class.

As the download progresses the singleton posts notifications with the cell index path that should update its progress view which I have working, apart from one problem!

As soon as one cell asks for a download and starts to receive post notifications the UI freezes until that cell and finished receiving all posts?

So where I want to be able to tap random cells and see each of their progress views being updated I get stuck with basically doing one download at a time.

Here is what I do:

I make a call to add a request to the queue passing in the cell’s index

In the singleton class that does all the work I have this:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
               
               // go make the call
               
               [self runRequest:queue];
            });

and in runRequest I have this:

         NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:q.name, @"name", q.cellrow, @"cell", nil];
         
         [[NSNotificationCenter defaultCenter] postNotificationName:kFileDidReceiveDataNotification object:nil userInfo:dict];

and in my view controller that listens to the posts I have this:

NSIndexPath *indexPath = [NSIndexPath indexPathForRow:[[dict objectForKey:@"cell"] intValue] inSection:0];

[tView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:NO];

So I do get the individual cell updating in the table view as a response to the post notification, but I cannot select another cell while that download is taking place. In fact if I try to scroll the tableview it is frozen … until the download is complete and then jumps as a response to my attempts to move it.

I thought as I was using dispatch_async this would be avoided?

What have I missed?

Thansk

As written, it looks like you’re posting your NSNotification on the same (background) thread where you’re making your service calls. I’m surprised that your notifications are being received at all - unless you’re listening for it on that thread then proceeding to also perform your UI work on that same (background) thread.

Don’t forget that you should never-ever-ever touch your user interface from any thread other than the main thread.

The most common pattern for this, when using dispatch_async, is to dispatch your work to another thread and then dispatch your UI update back to the main thread, as a nested dispatch:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{

    // Make my synchronous service calls or do other heavy work

    // now that it's done...
    dispatch_async(dispatch_get_main_queue(), ^{
        // Update my UI, such as a call to [tableView reloadData] or whatever
    });
});