While switching view on navigation bar, how to quit NSOperationQueue thread safely without EXC_BAD_ACCESS error
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_BA开发者_如何学GoD_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];
}
}
Have you tried calling [operationQueue cancelAllOperations]
in your viewWillDisappear
method?
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];
精彩评论