简体   繁体   English

iOS 11. KVO_IS_RETAINING_ALL_OBSERVERS_OF_THIS_OBJECT_IF_IT_CRASHES_AN_OBSERVER_WAS_OVERRELEASED_OR_SMASHED是什么意思?

[英]iOS 11. What the KVO_IS_RETAINING_ALL_OBSERVERS_OF_THIS_OBJECT_IF_IT_CRASHES_AN_OBSERVER_WAS_OVERRELEASED_OR_SMASHED is mean?

In the new iOS11, I get some strange exceptions. 在新的iOS11中,我得到了一些奇怪的例外。 I do not understand why this is happening. 我不明白为什么会这样。 In the previous iOS, there was no such exception. 在之前的iOS中,没有这样的例外。 Log attached: 附加日志:

 Crashed: com.apple.main-thread 0 libobjc.A.dylib 0x180a5e7e8 object_isClass + 16 1 Foundation 0x181f013e8 KVO_IS_RETAINING_ALL_OBSERVERS_OF_THIS_OBJECT_IF_IT_CRASHES_AN_OBSERVER_WAS_OVERRELEASED_OR_SMASHED + 68 2 Foundation 0x181eff8ec NSKeyValueWillChangeWithPerThreadPendingNotifications + 300 3 QuartzCore 0x18555a6dc CAAnimation_setter(CAAnimation*, unsigned int, _CAValueType, void const*) + 156 4 QuartzCore 0x18555d388 -[CAPropertyAnimation setKeyPath:] + 32 5 UIKit 0x18a9b1a08 -[UIImageView startAnimating] + 876 6 UIKit 0x18a9b0e78 -[UIActivityIndicatorView startAnimating] + 48 7 UIKit 0x18a9b0174 -[UIActivityIndicatorView _didMoveFromWindow:toWindow:] + 212 8 UIKit 0x18a95845c -[UIView(Internal) _didMoveFromWindow:toWindow:] + 712 9 UIKit 0x18a95845c -[UIView(Internal) _didMoveFromWindow:toWindow:] + 712 10 UIKit 0x18a95845c -[UIView(Internal) _didMoveFromWindow:toWindow:] + 712 11 UIKit 0x18a95845c -[UIView(Internal) _didMoveFromWindow:toWindow:] + 712 12 UIKit 0x18a95845c -[UIView(Internal) _didMoveFromWindow:toWindow:] + 712 13 UIKit 0x18a95845c -[UIView(Internal) _didMoveFromWindow:toWindow:] + 712 14 UIKit 0x18a95845c -[UIView(Internal) _didMoveFromWindow:toWindow:] + 712 15 UIKit 0x18a95845c -[UIView(Internal) _didMoveFromWindow:toWindow:] + 712 16 UIKit 0x18a957918 __45-[UIView(Hierarchy) _postMovedFromSuperview:]_block_invoke + 156 17 Foundation 0x181e7c59c -[NSISEngine withBehaviors:performModifications:] + 168 18 UIKit 0x18a95778c -[UIView(Hierarchy) _postMovedFromSuperview:] + 824 19 UIKit 0x18a96339c -[UIView(Internal) _addSubview:positioned:relativeTo:] + 1728 20 UIKit 0x18abb3158 __53-[_UINavigationParallaxTransition animateTransition:]_block_invoke_2 + 1660 21 UIKit 0x18a969a84 +[UIView(Animation) performWithoutAnimation:] + 104 22 UIKit 0x18ab23864 __53-[_UINavigationParallaxTransition animateTransition:]_block_invoke + 264 23 UIKit 0x18ac418a4 +[UIView(Internal) _performBlockDelayingTriggeringResponderEvents:] + 220 24 UIKit 0x18ab2321c -[_UINavigationParallaxTransition animateTransition:] + 1112 25 UIKit 0x18aae1720 -[UINavigationController _startCustomTransition:] + 3444 26 UIKit 0x18aa02e04 -[UINavigationController _startDeferredTransitionIfNeeded:] + 712 27 UIKit 0x18aa02a34 -[UINavigationController __viewWillLayoutSubviews] + 124 28 UIKit 0x18aa0295c -[UILayoutContainerView layoutSubviews] + 188 29 UIKit 0x18a959000 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1256 30 QuartzCore 0x1855290b4 -[CALayer layoutSublayers] + 184 31 QuartzCore 0x18552d194 CA::Layer::layout_if_needed(CA::Transaction*) + 332 32 QuartzCore 0x18549bf24 CA::Context::commit_transaction(CA::Transaction*) + 336 33 QuartzCore 0x1854c2340 CA::Transaction::commit() + 540 34 QuartzCore 0x1854c3180 CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*) + 92 35 CoreFoundation 0x1814f38b8 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 32 36 CoreFoundation 0x1814f1270 __CFRunLoopDoObservers + 412 37 CoreFoundation 0x1814f182c __CFRunLoopRun + 1292 38 CoreFoundation 0x1814122d8 CFRunLoopRunSpecific + 436 39 GraphicsServices 0x1832a3f84 GSEventRunModal + 100 40 UIKit 0x18a9bf880 UIApplicationMain + 208 

Who ever encountered this? 曾经遇到过这个? What is it and how to defeat it? 它是什么以及如何打败它?

It's related to KVO = Key-Value Observing. 它与KVO = Key-Value Observing有关。 Check if you're calling the function 检查您是否正在调用该功能

object.addObserver(self, forKeyPath:..., options:..., context:...)

somewhere; 某处; that's your KVO observer. 那是你的KVO观察者。 This class would also override the function 该类还将覆盖该函数

observeValue(forKeyPath:of:change:context:)

As the error message says, if you get a crash here, that means the observer was "overreleased" or "smashed". 正如错误信息所示,如果你在这里遇到崩溃,那就意味着观察者被“过度释放”或“被粉碎”。 I think that just means it was released while still observing the key path. 我认为这只是意味着它仍在观察关键路径时被释放。

How to fix it? 怎么解决?

Swift 3 斯威夫特3

If you need to fix it in Swift 3 (as I did), make sure you call removeObserver once you are no longer interested in observing the key path. 如果你需要在Swift 3中修复它(就像我一样),一旦你不再对观察关键路径感兴趣,请确保调用removeObserver The easiest way to do that is to add a deinit method to your observer: 最简单的方法是向观察者添加一个deinit方法:

deinit {
    object.removeObserver(self, forKeyPath:#keyPath(same.as.in.addObserver))
}

Make sure to replace object and the key path with the same references you used in addObserver ! 确保使用addObserver使用的相同引用替换object和键路径!

More info: https://cocoacasts.com/key-value-observing-kvo-and-swift-3/ 更多信息: https//cocoacasts.com/key-value-observing-kvo-and-swift-3/

Swift 4 / iOS Swift 4 / iOS

From Swift 4 / iOS 11 you can use blocks, as in this question: In Swift 4, how do I remove a block-based KVO observer? 从Swift 4 / iOS 11中你可以使用块,就像这个问题一样: 在Swift 4中,如何删除基于块的KVO观察者?

Instead of using the observeValue method, you can just add the observer like so: 您可以像这样添加观察者,而不是使用observeValue方法:

var observer: NSKeyValueObservation? = foo.observe(.value, options: [.new]) { (foo, change) in
   print(change.newValue)     // whatever needs to happen when the value changes
}

In iOS, you should still keep a reference to the observer and call invalidate on it at an appropriate time, eg in deinit or in viewWillDisappear . 在iOS中,您仍应保留对观察者的引用,并在适当的时间调用invalidate ,例如在deinitviewWillDisappear

Swift 4 / macOS Swift 4 / macOS

If you're developing for macOS 10.13 or newer, under certain conditions they no longer need to be removed. 如果您正在为macOS 10.13或更高版本开发,在某些情况下它们不再需要被删除。 Quote from the docs: 从文档引用:

Relaxed Key-Value Observing Unregistration Requirements 轻松的键值观察注销要求

Prior to 10.13, KVO would throw an exception if any observers were still registered after an autonotifying object's -dealloc finished running. 在10.13之前,如果在autonotifying对象的-dealloc完成运行后仍然注册了任何观察者,KVO将抛出异常。 Additionally, if all observers were removed, but some were removed from another thread during dealloc, the exception would incorrectly still be thrown. 另外,如果所有观察者都被删除了,但是在dealloc期间一些观察者被从另一个线程中删除了,那么异常将被错误地抛出。 This requirement has been relaxed in 10.13, subject to two conditions: 该要求已在10.13中放宽,但有两个条件:

  • The object must be using KVO autonotifying, rather than manually calling -will and -didChangeValueForKey: (ie it should not return NO from +automaticallyNotifiesObserversForKey:) 该对象必须使用KVO自动调整,而不是手动调用-will和-didChangeValueForKey :(即它不应该从+自动返回NONotifiesObserversForKey :)
  • The object must not override the (private) accessors for internal KVO state 对象不得覆盖内部KVO状态的(私有)访问器

If all of these are true, any remaining observers after -dealloc returns will be cleaned up by KVO; 如果所有这些都是真的,那么-dealloc返回后的任何剩余观察者将被KVO清理; this is also somewhat more efficient than repeatedly calling -removeObserver methods. 这比重复调用-removeObserver方法更有效。

Source: https://developer.apple.com/library/archive/releasenotes/Foundation/RN-Foundation/index.html 资料来源: https//developer.apple.com/library/archive/releasenotes/Foundation/RN-Foundation/index.html

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 卡在KVO_IS_RETAINING_ALL_OBSERVERS_OF_THIS_OBJECT_IF_IT_CRASHES_AN_OBSERVER_WAS_OVERRELEASED_OR_SMASHED - Stuck in KVO_IS_RETAINING_ALL_OBSERVERS_OF_THIS_OBJECT_IF_IT_CRASHES_AN_OBSERVER_WAS_OVERRELEASED_OR_SMASHED 斯威夫特 4 KVO_IS_RETAINING_ALL_OBSERVERS_OF_THIS_OBJECT_IF_IT_CRASHES_AN_OBSERVER_WAS_OVERRELEASED_OR_SMASHED - swift 4 KVO_IS_RETAINING_ALL_OBSERVERS_OF_THIS_OBJECT_IF_IT_CRASHES_AN_OBSERVER_WAS_OVERRELEASED_OR_SMASHED 使用KVO_IS_RETAINING_ALL_OBSERVERS_OF_THIS_OBJECTS_IF_IT_CRASHES_AN_OBSERVER_WAS_OVERRELEASED_OR_SMASHED创建时,NSProgress崩溃 - NSProgress crash on creating with KVO_IS_RETAINING_ALL_OBSERVERS_OF_THIS_OBJECTS_IF_IT_CRASHES_AN_OBSERVER_WAS_OVERRELEASED_OR_SMASHED 在UICollectionViewCell中添加Observer。 获取异常KVO_IS_RETAINING_ALL_OBSERVERS_OF_THIS_OBJECT_IF_IT_CRASHES_AN_OBSERVER_WAS_OVERRELEASED - Adding Observer in UICollectionViewCell. Getting exception KVO_IS_RETAINING_ALL_OBSERVERS_OF_THIS_OBJECT_IF_IT_CRASHES_AN_OBSERVER_WAS_OVERRELEASED 一名观察员被释放或砸了 - An observer was overreleased or smashed iOS应用程序崩溃,因为KVO观察者不再观察 - iOS App crashes because KVO observer is not observing anymore 在iOS中消除KVO中的Observer问题 - Remove Observer issue in KVO in ios iOS KVO - 无法删除观察者 - iOS KVO - Cannot remove an observer KVO - 如何检查对象是否是观察者? - KVO - How to check if an object is an observer? 从iOS7到iOS 11. *实现推送通知,我是否必须处理所有三种情况? - Implementing push notification from iOS7 to iOS 11.* do i have to handle all three cases?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM