blocks in uitableview didSelectRowAtIndexPath and passing autoreleased vars around causing nil behavior
I'm attempting to download an MP3 file from my server when a user selects a row using blocks and a dispatch_queue. Things seem to work great about 80% of the time.
Here is my thought process:
- When the user selects the row, update the UI to show that a download has begun (spinner)
- Add a block to a background thread to begin the download in the background (I use the thread blocking dataWithContentsOfURL method. I believe this is ok because it is on an async dispatch queue.
- on the main_queue, When the download is completed, create an AVAudioPlayer with the data from the dispatch queue.
- on the main_queue, Play sound file.
- on the main_queue, update UI to reflect that the sound is playing and the download is complete.
Like I said, this works perfectly 80% of the time. When something works 'most' of the time, it screams memory management issues.
So here is the snippet:
//download url
dispatch_queue_t downloadQueue = dispatch_queue_create("com.mycompany.audiodownload", NULL);
dispatch_retain(downloadQueue);
JAAudioMessageEvent *event = [se开发者_JAVA百科lf.cheers objectAtIndex:indexPath.row];
dispatch_async(downloadQueue, ^{
NSURL *sampleURL = [NSURL URLWithString:event.sample];
NSLog(@"start downloading file %@", sampleURL);
NSData *data = [NSData dataWithContentsOfURL:sampleURL];
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"play file %@", (data == nil) ? @"data file is nil":@"");
NSError *error;
self.eventPlayer = [[AVAudioPlayer alloc] initWithData:data error:&error];
if (error) {
NSLog(@"there was an error when playing %@", error);
}
[self.eventPlayer play];
self.eventPlayer.delegate = self;
[activityIndicator removeFromSuperview];
[activityIndicator release];
self.eventInProgress = NO;
});
dispatch_release(downloadQueue);
});
So the issue is that during this 20% of the time when things go wrong, it would seem as though the event is being released and I'm given a null url. I fetch a null url and I get an error when attempting to play said null url.
So the question becomes, how do I manage the event object so that it persists over the 2 async threads?
Thanks in advance
精彩评论