0

I'm using the MBProgressHUD library in my app, but there are times that the progress hud doesn't even show when i query extensive amount of data, or show right after the processing of data is finished (by that time i don't need the hud to be displayed anymore).

In another post i found out that sometimes UI run cycles are so busy that they don't get to refresh completely, so i used a solution that partially solved my problem: Now every request rises the HUD but pretty much half the times the app crashes. Why? That's where I need some help.

I have a table view, in the delegate method didSelectRowAtIndexPath i have this code:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{    
    [NSThread detachNewThreadSelector:@selector(showHUD) toTarget:self withObject:nil];
    ...
}

Then, I have this method:

- (void)showHUD {
    @autoreleasepool {
        [HUD show:YES];
    }
}

At some other point I just call:

[HUD hide:YES];

And well, when it works it works, hud shows, stays and then disappear as expected, and sometimes it just crashes the application. The error: EXC_BAD_ACCESS . Why?

By the way, the HUD object is already allocated in the viewDidLoad:

- (void)viewDidLoad
{
    [super viewDidLoad];

    ...

    // Allocating HUD
    HUD = [[MBProgressHUD alloc] initWithView:self.navigationController.view];
    [self.navigationController.view addSubview:HUD];

    HUD.labelText = @"Checking";
    HUD.detailsLabelText = @"Products";
    HUD.dimBackground = YES;
}
Renexandro
  • 464
  • 5
  • 13
  • Are you doing the processing on the main thread too? – chedabob Oct 08 '13 at 21:07
  • Yes, i´m fast enumerating some arrays, filling up some objects, displaying things in a collection view... yes, i think all of that is done on the main thread... – Renexandro Oct 08 '13 at 21:52

1 Answers1

0

You need to perform your processing on another thread, otherwise the processing is blocking MBProgressHud drawing until it completes, at which point MBProgressHud is hidden again.

NSThread is a bit too low-level for just offloading processing. I'd suggest either Grand Central Dispatch or NSOperationQueue.

http://jeffreysambells.com/2013/03/01/asynchronous-operations-in-ios-with-grand-central-dispatch http://www.raywenderlich.com/19788/how-to-use-nsoperations-and-nsoperationqueues

/* Prepare the UI before the processing starts (i.e. show MBProgressHud) */

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
   /* Processing here */

   dispatch_async(dispatch_get_main_queue(), ^{
      /* Update the UI here (i.e. hide MBProgressHud, etc..) */     
   });
}); 

This snippet will let you do any UI work on the main thread, before dispatching the processing to another thread. It then returns to the main thread once the processing is done, to allow you to update the UI.

chedabob
  • 5,835
  • 2
  • 24
  • 44
  • But the processing is in a delegate method, didSelectRowAtIndexPath in this case, how can I do this processing on another thread? MBProgress Show, and the Process are both inside the didSelect... how can i separate them in different threads? – Renexandro Oct 09 '13 at 14:43
  • Paste the code snippet into didSelectRowAtIndexPath. I've updated the answer to make it clearer how it works. – chedabob Oct 11 '13 at 09:07
  • Nop, it doesn't work, I mean, the hud appears and everything but after the task has been completed... any other idea? – Renexandro Oct 22 '13 at 22:51