2013-04-27 18 views
5

Sto visualizzando un testo non appena viene riprodotto un video. Sto usando una tecnica di notifica per raggiungere questo obiettivo. L'unico problema è che l'Observer viene chiamato due volte ogni tanto. Attiva il "itemDidFinishPlaying" due volte (e quindi il metodo con lo stesso nome). Non posso prevedere quando. Non so perché. Sembra casuale (so che questo suona strano) come se funzionasse bene diciamo 15 volte di seguito e la prossima volta che il comportamento si verifica inaspettatamente. Faccio una ricostruzione ed eseguo l'app e questa volta funziona ben 19 volte di fila prima di chiamare l'Observer due volte, ecc ... Imprevedibile. Ho provato tutti gli scenari per prevedere il bug al fine di risolverlo. È stato impossibile finora. Quindi ho 2 domande.Observer in NSNotification (itemDidFinishPlaying) RANDOMLY to called twice

1) Perché succede e "casualmente"?

2) Come risolvere questo problema di doppia chiamata?

anche questi 2 seguenti conversazioni non hanno aiutato:

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

How to stop the Observer in NSNotification to called twice?

Si prega di trovare il mio codice qui sotto:

- (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]; 

}

+0

Stai aggiungendo l'osservatore di notifica in azione del pulsante di riproduzione video? – NSUserDefault

+0

@NSUserDefault, nessun pulsante. Sto solo scorrendo per navigare. L'animazione viene riprodotta una volta visualizzata la pagina. – Armand

+0

dove stai chiamando questo - (void) playAnimation: (NSString *) il metodo theString? – NSUserDefault

risposta

7

Prova questo,

-(void)itemDidFinishPlaying { 

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

} 

Si può lavorare per voi.

Edit1:

Rimuovere l'osservatore notifica ogni volta prima di impostare la nuova one.Try lo scenario.It sotto garantirà, rimuovere l'osservatore precedente (anche esso non esiste nessun problema) e aggiunge il nuovo.

// 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

Siamo spiacenti, non ha funzionato. – Armand

+0

Per ora lo sto risolvendo con un'istruzione condizionale per stampare solo una volta il testo. Quindi se la notifica si verifica per la seconda volta di seguito, visualizza solo il testo una volta. Non l'approccio più sexy in giro ma per ora mi permette di andare avanti. – Armand

+0

Funziona finora con questa linea ... Grazie [[NSNotificationCenter defaultCenter] removeObserver: self]; – Armand

1

Questo mi capita solo durante AirPlay. Sto usando la seguente soluzione alternativa per ignorare la notifica duplicata.

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

    //Do your stuff here. 
} 

risposta di NSUserDefault funziona anche, ma poi si deve aggiungere nuovamente gli osservatori e potrebbe essere complicato a seconda della configurazione.