While switching view on navigation bar, how to quit NSOperationQueue thread safely without EXC_BAD_ACCESS error

StackOverflow https://stackoverflow.com/questions/2003445

  •  18-09-2019
  •  | 
  •  

Question

I am using an UITableView to show some string messages, and I use NSOperationQueue to hold an customized NSOperation which fetchs message in background thread. After one message fetched successfully, customized NSOperation will notify the UITableView controller to show it.

If I click back button on the navigation bar to switch from the UITableView to other view after all message loaded, every thing is OK. But, if i click the back button while some message still loading, an EXC_BAD_ACCESS is throw. I have checked that the exception happened while customized NSOperation notify UITableView controller with performSelectorOnMainThread method. Sound like the target UITableView controller is not invalid after view switched, but I think Navigation Controller will hold the view controller instance. May I know how to resolve this issue? Thanks.

Customized operation is initialized in the UITableView controller with following code:

StatusMessageLoadingOperation *operation = [[StatusMessageLoadingOperation alloc] 
                                            initWithData:person
                                            messageArray:cachedStatusMessages
                                            target:self 
                                            action:@selector(didFinishStatusMessages:)];
[operationQueue addOperation:operation];
[operation release];

The customized NSOperation class will update UITableView with following code:

- (void)main{
    for (int i = 0; i < [[person statusMessages] count]; i++) {
        [target performSelectorOnMainThread:action withObject:messageArray waitUntilDone:NO];
    }
}
Was it helpful?

Solution

Have you tried calling [operationQueue cancelAllOperations] in your viewWillDisappear method?

OTHER TIPS

Because popping a view controller calls that controller's -dealloc method, you may be releasing your queue too early, and some other part of your application is trying to access the queue or an operation inside it that no longer exists.

My recommendation is to put your NSOperationQueue *myQueue instance into your application delegate.

Use the app delegate's -applicationDidFinishLaunching: and -dealloc methods to initialize and release your queue and its contents.

By separating your queue from the view controller, your queue won't get released when you pop off a view controller from your navigation stack. It and any remaining operations should still be available to the rest of the application.

To make it easier to access your queue, set up the following macro definition:

#define UIAppDelegate ((MyAppDelegate *)[UIApplication sharedApplication].delegate)

You can then use the macro to access your queue as follows, e.g.:

NSLog(@"%@", [[UIAppDelegate myQueue] operations]);

Or, for example:

[[UIAppDelegate myQueue] addOperation:myOperation];
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top