繁体   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