1

ややこしいですがこんな感じです

AVPlayer *capturedPlayer = _player;
dispatch_async(_subtitlesQueue, ^{
    // Parse the requested subtitle track and create a subtitle time observer
    subripString = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
    subripEntries = [SubRipParser parse:subripString];
    if (!subripEntries.count)
        return;
    dispatch_async(dispatch_get_main_queue(), ^{
        _subtitlesTimeObserver = [capturedPlayer addPeriodicTimeObserverForInterval:CMTimeMake(1, 5)
                                                                              queue:_subtitlesQueue
                                                                         usingBlock:^(CMTime time){}];
    });
});

ボタンがクリックされると、上記のコードが呼び出されます。クラッシュします。私はGCDとキュー全体に不慣れなので、おそらく誤解しているかもしれませんが、上記はうまくいかないでしょうか?

メイン キューの呼び出しを同期に変更すると、機能します。クラッシュは、AVPlayer の makePeriodicCall (など) への呼び出しで、subtitleQueue から発生します。

カスタム シリアル キューの代わりに定期的な時間オブザーバーをメイン キューに追加すると、非同期呼び出しも機能します。ただし、ドキュメントによると、別のキューに追加しても問題ないはずです。

質問 2) そして、私がここにいる間、AVPlayer を「キャプチャ」する部分についても質問があります。そのような変数をキャプチャすることは十分に安全ですか、それとも __weak を使用してブロック内で NULL でないことを確認する必要がありますか? 私の状況では、AVPlayer を含むコントローラーはシングルトンであるため、アプリケーションの存続期間全体にわたって存在します。これにより、__weak 修飾子を使用しなくても問題ないと思います。私はこれを考えるのが正しいですか?

乾杯、助けてくれてありがとう!

編集: 例外は EXC_BAD_ACCESS コード 2 であるため、アクセスしてはならないものです。_subtitlesQueue を実行している別のスレッドで発生します。そして、[AVPlayerPeriodicCaller _effectiveRateChanged] への呼び出しで発生します。

また、_subtitlesQueue で外側の dispatch_async が呼び出される前、メイン キューで内側の dispatch_async が呼び出される前、およびメイン キューで addPeriodicTimeObserver が呼び出される前に、dispatch_async の内部で、capturedPlayer と _subtitlesQueue (ポインター値) の値を出力しました。それらはすべて同じです。

EDIT2:subtitleQueueでの定期的な時間オブザーバーの作成の周りに同期ブロックを追加すると、うまくいきます...

@synchronized(_subtitlesQueue) {
    _subtitlesTimeObserver = [capturedPlayer addPeriodicTimeObserverForInterval:CMTimeMake(1, 5)
                                                                          queue:_subtitlesQueue
                                                                     usingBlock:subtitleTimeObservedBlock];
}

全て

4

1 に答える 1