【问题标题】:NSNotificationCenter notification fired twice on swipeNSNotificationCenter 通知在滑动时触发了两次
【发布时间】:2015-01-28 11:30:47
【问题描述】:

我正在使用 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];
    }

}

【问题讨论】:

    标签: ios nsnotificationcenter


    【解决方案1】:

    我猜你已经切换下一首歌曲了。所以你不能用[_audioPlayer currentItem]删除通知观察者,因为它已经被改变了。

    更新 1。

    尝试替换第一行和第二行:

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

    【讨论】:

    • 做了,还是一样
    • 所以发这个方法:[[DataSingleton sharedMySingleton] nextTrack];.
    • 编辑了方法以包含相同的内容。请检查。
    【解决方案2】:

    我不会删除通知侦听器,而是在方法(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];
    }
    

    【讨论】:

    • 对不起,伙计,您的解决方案不能解决问题,它只是隐藏了一段时间。
    • 为什么说它不能解决问题?我认为删除通知是一种不好的做法
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多