2017-02-28 19 views
0

私はレートオブザーバーでAVPlayerを持っています。私observeValueForKeyPath方法でobserveValueForKeyPathでNSNotificationを送信

[self.player addObserver:self 
          forKeyPath:@"rate" 
          options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew 
          context:&RateContext]; 

、私は、プレイヤーが停止/開始されたときplayerLayerスーパービューが知っているように通知を送信しようとしています。私videoStalled

- (void)observeValueForKeyPath:(NSString *)keyPath 
        ofObject:(id)object 
        change:(NSDictionary<NSString *,id> *)change 
        context:(void *)context { 

    if ([keyPath isEqualToString:@"rate"]) { 
     if (self.player.rate == 0) { 
      [self.indicatorView startAnimating]; 
      dispatch_async(dispatch_get_main_queue(), ^{ 
       [[NSNotificationCenter defaultCenter] postNotificationName:@"playerStopped" object:nil]; 
      }); 
      [self videoStalled]; 
     }else if (self.player.rate == 1){ 
      [self.indicatorView stopAnimating]; 
      //dispatch_async(dispatch_get_main_queue(), ^{ 
      // [[NSNotificationCenter defaultCenter] postNotificationName:@"playerStarted" object:nil userInfo:dic]; 
      //}); 
     } 
     return; 
    } 

映像のより多くが、その後[self.player play]を呼び出してロードするまで、私は待ちます。通知の投稿をコメントアウトした場合にのみ、「レート」が呼び出され、ビデオは即座に再生されます。通知のコメントを外すと、「レート」は引き続き呼び出されますが、数秒後に再生されません。大きな遅れがどこから来ているかわからない

+0

遅延は、ディスパッチからメインUIスレッドまでです。通知を送信するためにUIスレッドに実際にディスパッチする必要はありません。また、メイン(UI)スレッドにいない場合、 '[self.indicatorView stopAnimating]を呼び出すとアプリがクラッシュするはずです – Lefteris

答えて

0

フローがどこに行き、どこの時間が費やされたかを示すために、いくつかのNSLog呼び出しを使用します。

- (void)observeValueForKeyPath:(NSString *)keyPath 
         ofObject:(id)object 
         change:(NSDictionary<NSString *,id> *)change 
         context:(void *)context { 

    if ([keyPath isEqualToString:@"rate"]) { 
     if (self.player.rate == 0) { 
      [self.indicatorView startAnimating]; 
      [self videoStalled]; 
      NSLog(@"stage 1"); 
      [[NSNotificationCenter defaultCenter] postNotificationName:@"playerStopped" object:nil]; 
     }else if (self.player.rate == 1){ 
      [self.indicatorView stopAnimating]; 
      //dispatch_async(dispatch_get_main_queue(), ^{ 
      // [[NSNotificationCenter defaultCenter] postNotificationName:@"playerStarted" object:nil userInfo:dic]; 
      //}); 
     } 
     return; 
    } 
} 

- (void) playerStopped 
{ 
    NSLog(@"stage 2"); 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     NSLog(@"stage 3"); 
     [self.player play]; 
    }); 
} 

こうすれば、スレッドを遅くするスレッドかどうかを確認できます。また、通知の代わりに別のオブザーバを使用して、playStoppedメソッドへの呼び出しをトリガすることもできます。私は、通知が時間の重大ではない状況で最もよく使用されることを発見しました。

関連する問題