This is by far the weirdest problem I've been stuck with.
I have a UIViewController on a UINavigationController and I want to call a method at viewDidAppear using NSInvocationOperation so it can run on a back thread when the view becomes visible.
The problem is that if I pop the view controller BEFORE the operation (in this case the testMethod method) completes running, the app crashes.
Everything works fine if I pop the view controller AFTER the operation runs it's course.
When the app crashes, it stops at [super dealloc] with "EXC-BAD-ACCESS" and gives me the following error.
bool _WebTryThreadLock(bool), xxxxxxxxx: Tried to obtain the web lock from a thread other than the main thread or the web thread. This may be a result of calling to UIKit from a secondary thread. Crashing now...
And this is my code (super simplified)..
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
NSInvocationOperation *theOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(testMethod) object:nil];
[operationQueue addOperation:theOperation];
[theOperation release];
}
- (void)testMethod
{
NSLog(@"do some stuff that takes a few seconds to complete");
}
- (void)dealloc
{
[_tableView release];
[super dealloc];
}
The testMethod has some code that takes a few seconds to complete. I only have a few clues and I really don't know how and where to start debugging this.
Clue #1: The funniest thing is that if I remove the [_tableView release]; from dealloc then the app doesn't crash. But of course this would cause a leak and I can't remove it.
Clue #2: I've tested this code on a separate "clean" UIViewController with a UITableView and to my surprise it didn't crash.
Clue #3: The app doesn't crash is the UITableView's datasource is set to nil in viewDidLoad.
Clue #4: The app doesn't seem crash if I use the same code in viewDidAppear somewhere else like an IBAction.
Clue #5: I've tried looking over stack data with NSZombie but it gives me tons of data and it leads me nowhere.
I have some very complicated code within my UITableViewDelegate and UITableViewDataSource and I really don't know where to start debugging this. I really hope I don't have to go through line by line or rewrite the entire thing because of this.
Any pointers on where I should be looking?
NSInvocation
is a bit unclear, but it seems to me that the invocation doesn't retain its target (your view controller) which would be a problem here because it tries to calltestMethod
after it's released. – omzNSBlockOperation
. – omz