刷新时NSNotificationCenter通知被触发两次

时间:2015-01-28 11:30:47

标签: ios nsnotificationcenter

我正在使用AVPlayer构建一个应用程序,它将播放来自api的歌曲。

当歌曲结束时,将播放下一首歌曲。为此,我使用以下代码:

- (void)viewDidLoad
{
[[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(playbackFinished:)
                                                 name:AVPlayerItemDidPlayToEndTimeNotification
                                               object:[_audioPlayer currentItem]];
}

-(void)playbackFinished:(NSNotification *)notification {
//    flagSkip = NO;
    NSLog(@"## %@ ", NSStringFromSelector(_cmd));
//    if(flagSkip == NO)
        [[DataSingleton sharedMySingleton] nextTrack];
//    else
//        flagSkip = NO;
}

在滑动手势上,将播放下一首歌曲。 为此,我删除通知观察者并再次添加它,如下所示:

- (IBAction)skipButtonPressed:(id)sender
{

        [[DataSingleton sharedMySingleton] nextTrack];
            [[NSNotificationCenter defaultCenter] removeObserver:self name:AVPlayerItemDidPlayToEndTimeNotification object:[_audioPlayer currentItem]];
            [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(playbackFinished:)
                                                     name:AVPlayerItemDidPlayToEndTimeNotification
                                                   object:[_audioPlayer currentItem]];

    }else{
        //
    }
}

但是当我滑动时,有时会调用通知方法。

我哪里出错了?我该如何解决这个问题?

编辑以包含[[DataSingleton sharedMySingleton] nextTrack]

    -(void)nextTrack{
    NSDictionary *prevTrackInfo; 
    if (currentIndex == -1){
        // We're at the start of a refilled list, so previousTrack should be 
        // the only thing in the cache dir. Clean it up.
        dispatch_queue_t removeFilesQueue;
        NSLog(@"## %@ removeFilesQueue", NSStringFromSelector(_cmd));

        removeFilesQueue = dispatch_queue_create("com.zombieprocess.removeFilesQueue", DISPATCH_QUEUE_SERIAL);

        dispatch_sync(removeFilesQueue, ^{
            // Code goes here
            NSError *error = nil;
            [fileMgr removeItemAtPath:[self getFeedBandsCacheDir] error:&error];
            [fileMgr createDirectoryAtPath:[self getFeedBandsCacheDir] withIntermediateDirectories:YES attributes:nil error:nil];
        });

        //dispatch_release(removeFilesQueue);

    } else{
        if (trackInfo){
            prevTrackInfo = trackInfo;
        }else{
            NSLog(@"nextTrack, attempting to store prevTrackInfo, no trackInfo for currentIndex: %d", currentIndex);
        }
    }

    currentIndex += 1;

    // We should not have this, but just in case
    if (currentIndex >= self.feedEntries.count) {
        // We are at the end. Get the feed again.
        NSLog(@"## %@ currentIndex >= self.feedEntries.count", NSStringFromSelector(_cmd));
        if (self.feedEntries.count == 0) {
            [self loadFeed];
            return;
        }
        currentIndex = 0; // This will loop it back to the beginning
//        [self loadFeed];
//        return;
    }

    trackInfo = [self.feedEntries objectAtIndex:currentIndex];

    [self dispatchPlayNotification];

    if (prevTrackInfo && [self isTrackCached:prevTrackInfo] && prevTrackInfo != trackInfo && feedEntries.count > [self numberOfSongsToCache]){
        NSLog(@"nextTrack, deleting cached copy: %@", [[prevTrackInfo objectForKey:@"file_url"] lastPathComponent]);
        [self deleteCachedTrack:prevTrackInfo completionBlock:^{
            [self fillDownloadQueue];
        }];
    } else {
        [self fillDownloadQueue];
    }

}

2 个答案:

答案 0 :(得分:0)

我猜你已经换了下一首歌。因此,您无法使用[_audioPlayer currentItem]删除通知观察者,因为它已经更改。

更新1。

尝试替换第1行和第2行:

[[NSNotificationCenter defaultCenter] removeObserver:self name:AVPlayerItemDidPlayToEndTimeNotification object:[_audioPlayer currentItem]];
[[DataSingleton sharedMySingleton] nextTrack];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackFinished:) name:AVPlayerItemDidPlayToEndTimeNotification object:[_audioPlayer currentItem]];

答案 1 :(得分:-1)

我会在方法(void)playbackFinished:(NSNotification *)notification中读取播放器上的当前状态,而不是删除通知侦听器。 例如:

- (IBAction)skipButtonPressed:(id)sender
{
      didSkipSong = YES;
      [[DataSingleton sharedMySingleton] nextTrack];

}

并在-(void)playbackFinished:(NSNotification *)notification

-(void)playbackFinished:(NSNotification *)notification {
  if(didSkipSong){
      didSkipSong = NO;
      return;
  }
  [[DataSingleton sharedMySingleton] nextTrack];
}