AVPlayerを使用してリモートビデオを再生すると、奇妙なクラッシュが発生しました。Fabricのクラッシュログから、システムスレッド(com.apple.avfoundation.playerlayer.configuration)でアプリがクラッシュします。クラッシュログは以下のとおりです。
Crashed: com.apple.avfoundation.playerlayer.configuration
0 libsystem_kernel.dylib 0x1839ac2e8 __pthread_kill + 8
1 libsystem_pthread.dylib 0x183ac12f8 pthread_kill$VARIANT$mp + 396
2 libsystem_c.dylib 0x18391afbc abort + 140
3 libsystem_malloc.dylib 0x1839e3ce4 szone_size + 634
4 QuartzCore 0x187ed75e8 -[CALayer dealloc] + 72
5 QuartzCore 0x187e75d90 CA::Transaction::commit() + 1052
6 AVFoundation 0x18973b4a8 -[AVPlayerLayer observeValueForKeyPath:ofObject:change:context:] + 684
7 Foundation 0x1847a2894 NSKeyValueNotifyObserver + 304
8 Foundation 0x1847bc364 -[NSObject(NSKeyValueObserverRegistration) _addObserver:forProperty:options:context:] + 204
9 Foundation 0x1847bc13c -[NSObject(NSKeyValueObserverRegistration) addObserver:forKeyPath:options:context:] + 124
10 AVFoundation 0x189760714 -[AVPlayer addObserver:forKeyPath:options:context:] + 204
11 AVFoundation 0x189890414 -[AVKVODispatcher startObservingValueAtKeyPath:ofObject:options:usingBlock:] + 136
12 AVFoundation 0x18989189c -[AVKVODispatcher(LegacyCallbackMethod) startObservingObject:weakObserver:forKeyPath:options:context:] + 152
13 AVFoundation 0x18973aef4 -[AVPlayerLayer _startObservingPlayer:] + 328
14 libdispatch.dylib 0x183816a54 _dispatch_call_block_and_release + 24
15 libdispatch.dylib 0x183816a14 _dispatch_client_callout + 16
16 libdispatch.dylib 0x18382096c _dispatch_queue_serial_drain$VARIANT$mp + 528
17 libdispatch.dylib 0x1838212fc _dispatch_queue_invoke$VARIANT$mp + 340
18 libdispatch.dylib 0x183821d20 _dispatch_root_queue_drain_deferred_wlh$VARIANT$mp + 404
19 libdispatch.dylib 0x18382a03c _dispatch_workloop_worker_thread$VARIANT$mp + 644
20 libsystem_pthread.dylib 0x183abef1c _pthread_wqthread + 932
21 libsystem_pthread.dylib 0x183abeb6c start_wqthread + 4
注意:すべてのクラッシュはiOS11で発生しました
このクラッシュが発生した理由を誰かが知っていますか?
あなたのスタックトレースから、それAVPlayerLayer observeValueForKeyPath:ofObject:change:context:
があなたの問題の原因であるように思われることに気づきました。したがって、KVOを実装している必要があると思いますAVPlayer
。
その場合、2つの点に注意してください。
登録解除要件を遵守する緩和されたKey-Value
•オブジェクトは、-willおよび-didChangeValueForKey:を手動で呼び出すのではなく、KVO自動通知を使用している必要があります(つまり、+ automaticallyNotizesObserversForKey:からNOを返さないようにする必要があります)。
•オブジェクトは、内部KVO状態の(プライベート)アクセサーをオーバーライドしてはなりません。
これが古いAPIとメソッドを使用して新しいAPIに実装されていることを確認するには、ここを参照してください。ドキュメントはまだ古いKVO実装に基づいているため、新しいAPIにはまだあまり役立ちません。ただし、ご覧のとおり、登録解除はで自動的に行われます。addObserver
removeObserver
deinit
AVFoundation
AVPlayer
KVOサポート(プライベートフレームワーク)の実装を非表示にしますが、これらの緩和された要件はに適用されない可能性がありますAVPlayer
。2018年のAppleからのこのコードスニペットはAVPlayer
、新しいKVO APIで使用しますが、deinit
メソッドでAVPlayer
登録を解除します(新しいAPIの緩和された登録解除要件を満たしていない疑いを確認します)。
もう1つの説明は、登録解除はで発生しますがdeinit
、必ずしもメインスレッドで実行されるとは限らないということです。これはAVPlayer
KVOにとって重要です。
一般的な状態の観察:メインスレッドでKVO変更通知を登録および登録解除する必要があります。これにより、別のスレッドで変更が行われた場合に部分的な通知を受け取る可能性が回避されます。
要約するAVPlayer
と、新しいAPIを使用してKVO forを実装する場合は、完了時に明示的に登録を解除する必要があります。また、登録コードと登録解除コードを、DispatchQueue.main.async { }
または同様のバリアント内にラップします。
ここでは、キーパスが有効であると想定しています(動的プロパティであることを確認してください)。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加