блоки в uitableview didSelectRowAtIndexPath и передача автоматически выпущенных переменных вокруг, вызывая нулевое поведение - PullRequest
1 голос
/ 14 июня 2011

Я пытаюсь загрузить файл MP3 с моего сервера, когда пользователь выбирает строку, используя блоки и dispatch_queue.Вещи, кажется, работают отлично в 80% случаев.

Вот мой мыслительный процесс:

  1. Когда пользователь выбирает строку, обновите пользовательский интерфейс, чтобы показать, что загрузка началась (счетчик)
  2. Добавить блокв фоновый поток, чтобы начать загрузку в фоновом режиме (я использую поток, блокирующий метод dataWithContentsOfURL. Я считаю, что это нормально, поскольку он находится в очереди асинхронной отправки.
  3. в main_queue, когда загрузка завершена,создайте AVAudioPlayer с данными из очереди отправки.
  4. в main_queue, Воспроизвести звуковой файл.
  5. в main_queue, обновите пользовательский интерфейс, чтобы отразить, что звук воспроизводится, и загрузка завершена.

Как я уже сказал, это прекрасно работает в 80% случаев. Когда что-то работает «большую часть времени», это вызывает проблемы с управлением памятью.

Так вот фрагмент:

    //download url
dispatch_queue_t downloadQueue = dispatch_queue_create("com.mycompany.audiodownload", NULL);
dispatch_retain(downloadQueue);
 JAAudioMessageEvent *event = [self.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);
});

Таким образом, проблема в том, что в течение этих 20% случаев, когда что-то идет не так, может показаться, что событие выходит, и мне дают нулевой URL.нулевой URL, и я получаю сообщение об ошибке при попытке воспроизведения указанного нулевого URL.

Таким образом, возникает вопрос, как мне управлять объектом события, чтобы он сохранялся в двух асинхронных потоках?

Спасибозаранее

...