uitableview中的块didSelectRowAtIndexPath并传递自动释放的变量,导致nil行为

时间:2011-06-14 19:59:18

标签: iphone memory-management grand-central-dispatch objective-c-blocks

当用户使用块和dispatch_queue选择行时,我正在尝试从我的服务器下载MP3文件。在80%的情况下,事情似乎很有效。

这是我的思考过程:

  1. 当用户选择行时,更新UI以显示下载已开始(微调)
  2. 将一个块添加到后台线程以在后台开始下载(我使用线程阻塞dataWithContentsOfURL方法。我相信这是可以的,因为它位于异步调度队列中。
  3. 在main_queue上
  4. ,下载完成后,使用调度队列中的数据创建一个AVAudioPlayer。
  5. 在main_queue上播放声音文件。
  6. 在main_queue上,更新UI以反映声音正在播放并且下载完成。
  7. 就像我说的那样,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时出错。

    所以问题就变成了,如何管理事件对象以使其在2个异步线程上持续存在?

    提前致谢

0 个答案:

没有答案