收到 -observeValueForKeyPath:ofObject:change:context: 消息但未处理
我对 KVO 比较陌生,所以我很可能违反了一些基本规则。我正在使用核心数据。
我的应用程序崩溃并显示以下消息: 我无法理解为什么 CGImage 参与观察在MeasurementPointer 对象上设置的值。
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '<CGImage 0x276fc0>: An -observeValueForKeyPath:ofObject:change:context: message was received but not handled.
Key path: measurementDescriptor
Observed object: <MeasurementPointer: 0x8201640> (entity: MeasurementPointer; id: 0x8200410 <x-coredata://EBEE0687-D67D-4B03-8C95-F4C60CFDC20F/MeasurementPointer/p75> ; data: {
measurementDescriptor = "0x260fd0 <x-coredata://EBEE0687-D67D-4B03-8C95-F4C60CFDC20F/MeasurementDescriptor/p22>";
})
Change: {
kind = 1;
new = "<MeasurementDescriptor: 0x262530> (entity: MeasurementDescriptor; id: 0x260fd0 <x-coredata://EBEE0687-D67D-4B03-8C95-F4C60CFDC20F/MeasurementDescriptor/p22> ; data: {\n measurementName = Temperature;\n measurementUnits = \"\\U00b0C\";\n sortString = nil;\n})";
}
Context: 0x0'
*** Call stack at first throw:
(
0 CoreFoundation 0x30897ed3 __exceptionPreprocess + 114
1 libobjc.A.dylib 0x3002f811 objc_exception_throw + 24
2 CoreFoundation 0x30897d15 +[NSException raise:format:arguments:] + 68
3 CoreFoundation 0x30897d4f +[NSException raise:format:] + 34
4 Foundation 0x34a13779 -[NSObject(NSKeyValueObserving) observeValueForKeyPath:ofObject:change:context:] + 60
5 Foundation 0x349b6acd NSKeyValueNotifyObserver + 216
6 Foundation 0x349b6775 NSKeyValueDidChange + 236
7 Foundation 0x349ae489 -[NSObject(NSKeyValueObserverNotification) didChangeValueForKey:] + 76
8 CoreData 0x3165b577 _PF_ManagedObject_DidChangeValueForKeyIndex + 102
9 CoreData 0x3165ac51 _sharedIMPL_setvfk_core + 184
10 CoreData 0x3165dc83 _svfk_0 + 10
11 SPARKvue 0x000479f1 -[MeasurementViewController doneAction:] + 152
12 CoreFoundation 0x3083f719 -[NSObject(NSObject) performSelector:withObject:withObject:] + 24
13 UIKit 0x31eb1141 -[UIApplication sendAction:to:from:forEvent:] + 84
14 UIKit 0x31f08315 -[UIBarButtonItem(UIInternal) _sendAction:withEvent:] + 92
15 CoreFoundation 0x3083f719 -[NSObject(NSObject) performSelector:withObject:withObject:] + 24
16 UIKit 0x31eb1141 -[UIApplication sendAction:to:from:forEvent:] + 84
17 UIKit 0x31eb10e1 -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 32
18 UIKit 0x31eb10b3 -[UIControl sendAction:to:forEvent:] + 38
19 UIKit 0x31eb0e05 -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 356
20 UIKit 0x31eb1453 -[UIControl touchesEnded:withEvent:] + 342
21 UIKit 0x31eafddd -[UIWindow _sendTouchesForEvent:] + 368
22 UIKit 0x31eaf757 -[UIWindow sendEvent:] + 262
23 UIKit 0x31eaa9ff -[UIApplication sendEvent:] + 298
24 UIKit 0x31eaa337 _UIApplicationHandleEvent + 5110
25 GraphicsServices 0x31e4504b PurpleEventCallback + 666
26 CoreFoundation 0x3082cce3 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 26
27 CoreFoundation 0x3082cca7 __CFRunLoopDoSource1 + 166
28 CoreFoundation 0x3081f56d __CFRunLoopRun + 520
29 CoreFoundation 0x3081f277 CFRunLoopRunSpecific + 230
30 CoreFoundation 0x3081f17f CFRunLoopRunInMode + 58
31 GraphicsServices 0x31e445f3 GSEventRunModal + 114
32 GraphicsServices 0x31e4469f GSEventRun + 62
33 UIKit 0x31e51123 -[UIApplication _run] + 402
34 UIKit 0x31e4f12f UIApplicationMain + 670
35 SPARKvue 0x000031ff main + 70
36 SPARKvue 0x000031b4 start + 40
)
terminate called after throwing an instance of 'NSException'
Program received signal: “SIGABRT”.
触发此事件的所有事情是:
[[self measurementPointer] setMeasurementDescriptor:descriptor];
鉴于此,
[[meterDisplay measurementPointer] addObserver:self
forKeyPath:@"measurementDescriptor"
options:NSKeyValueObservingOptionNew
context:nil];
基本上,MeasurementPointer 对象指向MeasurementDescriptor 对象 - 并且两者都是 NSManagedObject 子类。 MeasurementDescriptor 对象描述特定的“测量”和“单位”组合(例如“温度 (°C)”或“风速 (mph)”)。测量描述符类似于单例,每个唯一的测量单位组合只有一个。
测量指针由其他对象引用 - 模型对象和控制器对象。 MeasurementPointer 引用MeasurementDescriptor。许多对象有兴趣了解MeasurementPointer 何时开始引用新的/不同的MeasurementDescriptor。例如,此类更改可能会导致图形显示的轴发生更改。或者,在上面的代码中,可能会导致仪表显示屏显示不同的样本(来自选定的一组样本)。
我认为根本问题是 CGImage 正在接收一条不适合它的消息...不幸的是,这是间歇性的,所以我无法找到触发它的模式。
I am relatively new to KVO, so there is a good chance that I am violating some fundamental rule. I am using Core Data.
My app crashes with the following message: And what I can't understand is why a CGImage is getting involved in observing a value that is set on a MeasurementPointer object.
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '<CGImage 0x276fc0>: An -observeValueForKeyPath:ofObject:change:context: message was received but not handled.
Key path: measurementDescriptor
Observed object: <MeasurementPointer: 0x8201640> (entity: MeasurementPointer; id: 0x8200410 <x-coredata://EBEE0687-D67D-4B03-8C95-F4C60CFDC20F/MeasurementPointer/p75> ; data: {
measurementDescriptor = "0x260fd0 <x-coredata://EBEE0687-D67D-4B03-8C95-F4C60CFDC20F/MeasurementDescriptor/p22>";
})
Change: {
kind = 1;
new = "<MeasurementDescriptor: 0x262530> (entity: MeasurementDescriptor; id: 0x260fd0 <x-coredata://EBEE0687-D67D-4B03-8C95-F4C60CFDC20F/MeasurementDescriptor/p22> ; data: {\n measurementName = Temperature;\n measurementUnits = \"\\U00b0C\";\n sortString = nil;\n})";
}
Context: 0x0'
*** Call stack at first throw:
(
0 CoreFoundation 0x30897ed3 __exceptionPreprocess + 114
1 libobjc.A.dylib 0x3002f811 objc_exception_throw + 24
2 CoreFoundation 0x30897d15 +[NSException raise:format:arguments:] + 68
3 CoreFoundation 0x30897d4f +[NSException raise:format:] + 34
4 Foundation 0x34a13779 -[NSObject(NSKeyValueObserving) observeValueForKeyPath:ofObject:change:context:] + 60
5 Foundation 0x349b6acd NSKeyValueNotifyObserver + 216
6 Foundation 0x349b6775 NSKeyValueDidChange + 236
7 Foundation 0x349ae489 -[NSObject(NSKeyValueObserverNotification) didChangeValueForKey:] + 76
8 CoreData 0x3165b577 _PF_ManagedObject_DidChangeValueForKeyIndex + 102
9 CoreData 0x3165ac51 _sharedIMPL_setvfk_core + 184
10 CoreData 0x3165dc83 _svfk_0 + 10
11 SPARKvue 0x000479f1 -[MeasurementViewController doneAction:] + 152
12 CoreFoundation 0x3083f719 -[NSObject(NSObject) performSelector:withObject:withObject:] + 24
13 UIKit 0x31eb1141 -[UIApplication sendAction:to:from:forEvent:] + 84
14 UIKit 0x31f08315 -[UIBarButtonItem(UIInternal) _sendAction:withEvent:] + 92
15 CoreFoundation 0x3083f719 -[NSObject(NSObject) performSelector:withObject:withObject:] + 24
16 UIKit 0x31eb1141 -[UIApplication sendAction:to:from:forEvent:] + 84
17 UIKit 0x31eb10e1 -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 32
18 UIKit 0x31eb10b3 -[UIControl sendAction:to:forEvent:] + 38
19 UIKit 0x31eb0e05 -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 356
20 UIKit 0x31eb1453 -[UIControl touchesEnded:withEvent:] + 342
21 UIKit 0x31eafddd -[UIWindow _sendTouchesForEvent:] + 368
22 UIKit 0x31eaf757 -[UIWindow sendEvent:] + 262
23 UIKit 0x31eaa9ff -[UIApplication sendEvent:] + 298
24 UIKit 0x31eaa337 _UIApplicationHandleEvent + 5110
25 GraphicsServices 0x31e4504b PurpleEventCallback + 666
26 CoreFoundation 0x3082cce3 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 26
27 CoreFoundation 0x3082cca7 __CFRunLoopDoSource1 + 166
28 CoreFoundation 0x3081f56d __CFRunLoopRun + 520
29 CoreFoundation 0x3081f277 CFRunLoopRunSpecific + 230
30 CoreFoundation 0x3081f17f CFRunLoopRunInMode + 58
31 GraphicsServices 0x31e445f3 GSEventRunModal + 114
32 GraphicsServices 0x31e4469f GSEventRun + 62
33 UIKit 0x31e51123 -[UIApplication _run] + 402
34 UIKit 0x31e4f12f UIApplicationMain + 670
35 SPARKvue 0x000031ff main + 70
36 SPARKvue 0x000031b4 start + 40
)
terminate called after throwing an instance of 'NSException'
Program received signal: “SIGABRT”.
All that is happening to trigger this is:
[[self measurementPointer] setMeasurementDescriptor:descriptor];
Given this,
[[meterDisplay measurementPointer] addObserver:self
forKeyPath:@"measurementDescriptor"
options:NSKeyValueObservingOptionNew
context:nil];
Basically, MeasurementPointer objects point to MeasurementDescriptor objects - and both are NSManagedObject subclasses. MeasurementDescriptor objects describe a specific 'measurement' and 'unit' combination (e.g., "Temperature (°C)" or "Wind Speed (mph)"). MeasurementDescriptors are something like singletons to the extent that there is only one for each unique measurement-unit combo.
MeasurementPointers are referenced by other objects - both Model objects and Controller objects. A MeasurementPointer references a MeasurementDescriptor. Many objects are interested in knowing when a MeasurementPointer starts referencing a new/different MeasurementDescriptor. Such a change might cause a graph display's axis to change, for example. Or, in the code above, might cause a meter display to show a different sample (from a selected set of samples).
I think that fundamental problem is that a CGImage is receiving a message that is not intended for it... unfortunately, this is intermittent, so I have not been able to find a pattern that triggers it.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您有一个对象被释放并且没有停止观察另一个对象。浏览所有
-addObserver...
调用,并确保它们至少在-dealloc
-removeObserver... 调用相匹配> 并可能在-viewDidUnload
中,具体取决于您的应用程序结构。You have an object that got dealloc'ed and did not stop observing another object. Walk through all of your
-addObserver...
calls and make sure they are matched with-removeObserver...
calls at least in the-dealloc
and possibly in the-viewDidUnload
depending on your application structure.当我将
observeValueForKeyPath
方法发送到super
时,我看到了此错误,而我尚未将其注册为更改的观察者。 Apple 文档说“请确保调用超类的实现 [ofobserveValueForKeyPath
] 如果它实现了它。”我的解决办法是将: 更改
为:
迅速:
I saw this error when I sent the
observeValueForKeyPath
method tosuper
, which I had not registered as an observer for the change. Apple docs say "Be sure to call the superclass's implementation [ofobserveValueForKeyPath
] if it implements it."My fix was to change:
to:
In swift:
我通过意外地将目标作为观察者(而不是自己)传递而遇到了这个问题,如下所示:
错误消息对于识别这一点完全没有帮助,所以只是想我会发布以防其他人做同样的事情。
I ran into this problem by accidentally passing the target in as the observer (instead of self) like so:
The error message was not at all helpful in identifying this so just thought I'd post in case anyone else does the same thing.
我遇到了同样的问题,但就我而言,我观察到了不同的背景。然后我将所有内容放在相同的上下文中,崩溃就消失了。我希望这对某人有帮助。
I had the same problem, but in my case I was observing a different context. Then I put all in the same context and the crash was gone. I hope this helps someone.
对我来说,我忘记添加
override funcobserveValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?)
来实际执行一些操作keyPath 被观察到。这是 Swift 版本的示例。在
viewDidLoad
中添加观察者并在deinit
中删除它们:For me I forgot to add in
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?)
to actually do something with the keyPath getting observed.Here's an example of the Swift version. Add the observers in
viewDidLoad
and remove them indeinit
: