0

I'm having some random crashes at this part of my code:

-(void) goBack {

        [self performSelectorInBackground:@selector(addActivityIndicator) withObject:nil];

        [self.navigationController popViewControllerAnimated:YES];

        }

- (void)addActivityIndicator {
        @autoreleasepool {

            UIActivityIndicatorView *activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];

            UIBarButtonItem * barButton = [[UIBarButtonItem alloc] initWithCustomView:activityView];

            [activityView startAnimating];

            self.navigationItem.leftBarButtonItem = barButton;

        }
    }

When I want to exit the screen where these method exists, the other ViewController have to process some data. To inform the user that processing is occurring I add an activity indicator to the left button in my navigation bar.

The problem is that sometimes I get an exc_bad_access in addActivityIndicator method. The frequency is very random, sometimes the XCode shows the error at the end of @autoreleasepool, sometimes at the line self.navigationItem.leftBarButtonItem = barButton;

I imagine that sometimes my viewController is destroyed but the thread is still running and try to access the navigationItem of a object that don't exists anymore. But I'm not sure if that is the problem and I don't know how to fix it.

I'm using ARC in my project and this problem occurs in all iOS versions that I tested.

Please, anyone can explain me what is happening and how can I fix this?

Thanks.

Rafael
  • 1,655
  • 3
  • 17
  • 25
  • I don't understand why you are doing this. What's the point of amending the navigation item of a view that you are removing from the navigation stack? – jrturton Oct 03 '12 at 19:11
  • Because the view that will appear have to proccess some heavy stuff and my current view will not disappear until that proccessing is finished. Maybe there is a better way to indicate that... – Rafael Oct 03 '12 at 19:15

2 Answers2

8

You should never do UIKit stuff in the background.

fzwo
  • 9,842
  • 3
  • 37
  • 57
  • Thanks for your answer. But if I put my "addActivityIndicator" code inside my goBack function the UI keeps freezed and the ActivityIndicador only appears when the view is disappearing. What is the correct way to do that? – Rafael Oct 03 '12 at 19:13
1

By calling [self performSelectorInBackground:@selector(addActivityIndicator) withObject:nil]; you are updating the UI on a background thread. You should only ever update the UI on the main thread.

Edit

Based on your comment you are trying to have the UI update before the view pops. The way to do that would be:

[self addActivityIndicator]

[navigationController performSelector:@selector(popViewControllerAnimated:) withObject:[NSNumber numberWithBool:YES] afterDelay:0];

You could also look into dispatch_after

ChrisH
  • 4,468
  • 2
  • 33
  • 42
  • Thanks for your answer. But if I put my "addActivityIndicator" code inside my goBack function the UI keeps freezed and the ActivityIndicador only appears when the view is disappearing. What is the correct way to do that? – Rafael Oct 03 '12 at 19:16
  • Perhaps add the activity indicator in `viewDidLoad`, but set it to hidden (hidden is `YES`). When you want to display the activity indicator, set hidden to `NO`. – Wolfgang Schreurs Oct 03 '12 at 19:21