2013-04-27 8 views
5

ビデオの再生が終了するとすぐにテキストを表示しています。私はこれを達成するための通知方法を使用しています。唯一の問題は、Observerが毎回2回呼び出されることです。これは "itemDidFinishPlaying"を2回(したがって同じ名前のメソッド)トリガします。私はいつ予測できないのですか。どうしてか分かりません。ランダムに見える(私はこれが奇妙に聞こえる)。うまく動いているように、15回連続して言いましょう。私はアプリケーションを再構築して実行し、今度はObserverを2回呼び出す前に19回連続してうまく動作します...予測不能です。私はそれを修正するためにバグを予測するためにあらゆるシナリオを試しました。今まで不可能だった。だから私は2つの質問があります。NSNotificationのオブザーバ(itemDidFinishPlaying)2回呼び出されるランダムに

1)なぜ、「ランダムに」起こるのですか?

2)このダブルコール問題を解決するにはどうすればよいですか?

また、これらの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; 

}

を - (無効)itemDidFinishPlaying {

[self displayContent: pageContent]; 

}

+0

ビデオ再生ボタン操作で通知オブザーバを追加していますか? – NSUserDefault

+0

@NSUserDefault、ボタンなし。私はナビゲートするためにスワイプしています。ページが表示されたらアニメーションが再生されます。 – Armand

+0

あなたがこれを呼び出す場所 - (void)playAnimation:(NSString *)theStringメソッド? – NSUserDefault

答えて

7

-(void)itemDidFinishPlaying { 

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

} 

それはあなたのために働くことがあり、これを試してみてください。

EDIT1:あなたはscenario.It下に新しいone.Tryを設定する前に

は、通知オブザーバごとにタイムを取り外し、確実に(たとえそれが何の問題も存在しません)以前のオブザーバを削除します新しいものを追加します。

// 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]; 
+0

申し訳ありませんが、うまくいきませんでした。 – Armand

+0

今のところ、私はテキストを1回だけ印刷するために条件文で解決します。したがって、2回目の通知があった場合は、1回だけテキストが表示されます。一番セクシーなアプローチではありませんが、今のところ私は前進することができます。 – Armand

+0

これまでのところ、この行で動作しています...ありがとう[[NSNotificationCenter defaultCenter] removeObserver:self]; – Armand

1

これはAirPlayの間にのみ発生します。重複した通知を無視するために、次の回避策を使用しています。

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

    //Do your stuff here. 
} 

NSUserDefaultの答えも動作しますが、その後は再びオブザーバーを追加する必要がありますし、あなたのセットアップに応じて複雑になることができます。

関連する問題