【问题标题】:Observer in NSNotification (itemDidFinishPlaying) RANDOMLY to called twiceNSNotification (itemDidFinishPlaying) 中的观察者随机调用两次
【发布时间】:2013-04-27 04:51:24
【问题描述】:

视频播放完毕后,我会立即显示文字。我正在使用通知技术来实现这一点。唯一的问题是 Observer 不时被调用两次。它触发了两次“itemDidFinishPlaying”(因此触发了同名的方法)。我无法预测何时。我不知道为什么。它看起来是随机的(我知道这听起来很奇怪)就像它工作正常让我们说连续 15 次,下一次这种行为突然发生。我进行了重建并运行了该应用程序,这次它在调用 Observer 两次之前连续运行了 19 次,等等......不可预测。我已经尝试了所有场景来预测错误以修复它。到目前为止是不可能的。所以我有两个问题。

1) 为什么它会“随机”发生?

2) 如何解决这个双重调用问题?

以下两个对话也没有帮助:

Why the Observer in NSNotification called twice....?

How to stop the Observer in NSNotification to called twice?

请在下面找到我的代码:

- (void) playAnimation: (NSString *) theString {

UIView *thisCurrentView = self.currentView;
UIView *thisReplacementView = [[UIView alloc] init];

//[avPlayer pause];
[self replaceView: thisCurrentView withView: thisReplacementView];

NSString *filepath = [[NSBundle mainBundle] pathForResource:theString ofType:@"mov"];
NSURL *fileURL = [NSURL fileURLWithPath:filepath];


 // First create an AVPlayerItem
 AVPlayerItem* playerItem = [AVPlayerItem playerItemWithURL:fileURL];

 // Subscribe to the AVPlayerItem's DidPlayToEndTime notification.
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(itemDidFinishPlaying) name:AVPlayerItemDidPlayToEndTimeNotification object:playerItem];

 // Pass the AVPlayerItem to a new player
 controlledPlayer = [[AVPlayer alloc] initWithPlayerItem:playerItem];


AVPlayerLayer *animatedLayer = [AVPlayerLayer playerLayerWithPlayer:controlledPlayer];


[animatedLayer setFrame:CGRectMake(0, 0, 1024, 1024)];
[thisReplacementView.layer addSublayer: animatedLayer];


// Begin playback
[controlledPlayer play];

// Clear some content
[self displayNoContent];

pageContent = theString;


playingStatus = YES;

}

-(void)itemDidFinishPlaying {

[self displayContent: pageContent];

}

【问题讨论】:

  • 您是否在视频播放按钮操作中添加通知观察者?
  • @NSUserDefault,没有按钮。我只是滑动导航。页面显示后播放动画。
  • 你在哪里调用这个 - (void) playAnimation: (NSString *) theString 方法?
  • 在 (IBAction)HandleSwipe:(UISwipeGestureRecognizer *)sender 方法中,在用户滑动显示下一页或上一页后启动动画。
  • 目前为止,这项调整正在发挥作用 [[NSNotificationCenter defaultCenter] removeObserver:self];

标签: ios objective-c uitextview avplayer nsnotification


【解决方案1】:

试试这个,

-(void)itemDidFinishPlaying {

      [self displayContent: pageContent];
      [[NSNotificationCenter defaultCenter] removeObserver:self name:AVPlayerItemDidPlayToEndTimeNotification object:playerItem];

}

它可能对你有用。

EDIT1:

在设置新的通知观察者之前,每次都删除。试试下面的场景。它将确保,删除以前的观察者(即使它不存在没有问题)并添加新的。

// Subscribe to the AVPlayerItem's DidPlayToEndTime notification.

[[NSNotificationCenter defaultCenter] removeObserver:self name:AVPlayerItemDidPlayToEndTimeNotification object:playerItem];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(itemDidFinishPlaying) name:AVPlayerItemDidPlayToEndTimeNotification object:playerItem];

【讨论】:

  • 现在我用一个条件语句来解决它,只打印一次文本。因此,如果通知连续第二次发生,它只会显示一次文本。不是最性感的方法,但现在它可以让我继续前进。
  • 到目前为止,这条线一直在工作...谢谢 [[NSNotificationCenter defaultCenter] removeObserver:self];
  • 您的问题的唯一原因应该是,您不止一次添加了通知观察者。请检查您的代码一次,甚至在每次添加之前删除观察者。这样可以确保您没有以前的观察者同名。请检查我编辑的答案。
【解决方案2】:

这只会在 AirPlay 期间发生在我身上。我正在使用以下解决方法来忽略重复通知。

if ([notificaiton.object isEqual:self.player.currentItem] && (self.player.rate > 0))
{
    [self.player pause];

    //Do your stuff here.
}

NSUserDefault 的答案也有效,但是您必须再次添加观察者,并且根据您的设置可能会很复杂。

【讨论】:

    【解决方案3】:

    1) 验证您只有一个观察者,而不是从视图控制器中悬空未按预期释放的观察者。

    2) 如果您确认只有一个观察者,听起来您可以使用跟踪变量并在第一个通知实例之后忽略任何内容。不优雅,但它应该可以工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多