I got an iPhone crash report with a SIGSEGV and I think I've narrowed down the possible cause and a solution. Since crashes caused by threads are hard to debug I can't repro this problem, but could use some help with my hypothesis - is it sound?
My code uses ASIHttpRequest to download a set of files using an ASINetWorkQueue. Here is a simplified sample
//initialize download queue and do this code block in a loop for each file
NSURL *fileURL = [NSURL URLWithString:...
__block ASIHTTPRequest *fileRequest = [ASIHTTPRequest requestWithURL:fileURL];
[fileRequest setCompletionBlock:^{
//do some stuff
}];
[fileRequest setFailedBlock:^{
NSString *someError = [NSString stringWithFormat:...
[self someErrorMethod:someError];
}];
[downloadQueue addOperation:...
-(void)someErrorMethod(NSString *errorMessage) {
DDLogWarn(errorMessage);
if ([self downloadQueue]) {
for (ASIHTTPRequest *request in [[self downloadQueue] operations]) {
[request clearDelegatesAndCancel];
}
[[self downloadQueue] reset];
}
}
The top 2 lines of the crash report are
- libobjc.A.dylib 0x31846fbc objc_msgSend + 15
- MyApp 0x0002cab5 -[Myapp someErrorMethod:] (MyApp.m:)
My thinking for why this happened
- A file download fails and the failed block is called
- It goes through every request and clears delegates and cancels them and then resets the queue
- However, while it is till running, another file download fails and enters the failed block callback
- However, since it has now been cancelled, its failed block has been released
- When the code tries to log the error message, its memory has been released and unpredictable results follow
Does this make sense? Since I am newish to Objective-C, is my analysis correct or am I missing something obvious?
I am thinking of using a lock to make the errorMethod thread safe with the hope that it will fix this issue. Does that sound like the right solution based on the code above?
Thanks