开发者

blocks in uitableview didSelectRowAtIndexPath and passing autoreleased vars around causing nil behavior

开发者 https://www.devze.com 2023-03-13 04:24 出处:网络
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.

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:

  1. When the user selects the row, update the UI to show that a download has begun (spinner)
  2. 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.
  3. on the main_queue, When the download is completed, create an AVAudioPlayer with the data from the dispatch queue.
  4. on the main_queue, Play sound file.
  5. 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

0

精彩评论

暂无评论...
验证码 换一张
取 消