4

In my app, I have a UITableViewController which loads calculated data from my Core Data store. This can take quite some time and hangs the main thread, so to give the user visual feedback, I have installed the MBProgressHUD widget which will show a progress indicator (just the spinning wheel) while the calculation method runs in a separate thread.

This is fine, except that the user can still exit the UITableViewController if they think it's taking too long. Of course, this is a good thing, except that when the separate thread concludes its operation, it still tries to call its delegate (the UITableViewController) to hide the MBProgressHUD. This causes a crash because since the user already exited the UITableViewController, it has dealloc'd and release'd itself.

MBProgressHUD has the following code to try to stop this:

if(delegate != nil && [delegate conformsToProtocol:@protocol(MBProgressHUDDelegate)]) {
    if([delegate respondsToSelector:@selector(hudWasHidden)]) {
        [delegate performSelector:@selector(hudWasHidden)];
    }
}

However, my app somehow seems to still be running this inner code ([delegate performSelector:@selector(hudWasHidden)]) even though the UITableViewController is totally gone--causing the app to crash.

Any suggestions? I am not running with NSZombiesEnabled.

Jason
  • 14,517
  • 25
  • 92
  • 153

2 Answers2

4

From your UITableViewController viewWillDisappear, viewDidDisappear or dealloc method, set the MBProgressHUD.delegate = nil;

picciano
  • 22,341
  • 9
  • 69
  • 82
0

Once the user has exited the table controller, the delegate property of the hud points to a deallocated object (= a memory zone that could contain anything). That causes the crash when the computing thread ends and tries to send any message to the delegate.

In your table view controller dealloc, you must set the hud delegate to nil.

Jilouc
  • 12,684
  • 4
  • 46
  • 43