簡體   English   中英

KVO導致iOS 11 AVPlayer崩潰

[英]iOS 11 AVPlayer crash when KVO

使用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:似乎是造成您問題的原因。 因此,我相信您必須為AVPlayer實現KVO。

在這種情況下,請注意兩點:

  1. 使用新的鍵值觀察iOS 11 API,您可以放寬要求 ,但是這些不必從觀察中注銷的要求僅在以下情況下適用:

寬松的鍵值觀察取消注冊要求

•對象必須使用KVO自動通知,而不是手動調用-will和-didChangeValueForKey:(即,它不應從+ automaticallyNotifyObserversForKey:返回NO)。

•對象不得覆蓋內部KVO狀態的(專用)訪問器。

請參見此處,以了解如何使用舊的API addObserverremoveObserver方法在新的API中實現此功能。 請注意,該文檔對於新API仍然不是很有幫助,因為它仍然基於舊的KVO實現。 但是,如您所見,注銷會在deinit自動發生。

AVFoundation隱藏了AVFoundation支持的AVPlayer實現(這是一個私有框架),但是這些寬松的要求很可能不適用於AVPlayer Apple於2018年發布的代碼段將AVPlayer與新的KVO API結合使用,但仍以deinit方法注銷(確認懷疑AVPlayer不滿足新API寬松的注銷要求)。

另一個解釋是注銷發生在deinit ,但不一定在主線程中完成。 這對於AVPlayer KVO很重要。

  1. 重要的原因可以在docs中找到:

一般狀態觀察:您應該在主線程上注冊和注銷KVO更改通知。 如果在另一個線程上進行了更改,這避免了接收到部分通知的可能性。

總而言之,如果使用新的API為AVPlayer實施KVO,則需要在完成后顯式注銷。 另外,將您的注冊和注銷代碼包裝在DispatchQueue.main.async { }或類似的變量中。

我在這里假設您的密鑰路徑是有效的(只需確保它們是動態屬性)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM