NSNotificationCenter 通知在滑动时触发了两次
Posted
技术标签:
【中文标题】NSNotificationCenter 通知在滑动时触发了两次【英文标题】:NSNotificationCenter notification fired twice on swipe 【发布时间】: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];
【问题讨论】:
【参考方案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];
【讨论】:
对不起,伙计,您的解决方案不能解决问题,它只是隐藏了一段时间。 为什么说它不能解决问题?我认为删除通知是一种不好的做法以上是关于NSNotificationCenter 通知在滑动时触发了两次的主要内容,如果未能解决你的问题,请参考以下文章
选择器没有收到来自 NSNotificationCenter (iOS) 的通知
iOS NSNotificationCenter 移除通知带来的crash
NSNotificationCenter 观察者没有收到通知