Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

An -observeValueForKeyPath:ofObject:change:context: message was received but not handled

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.

like image 471
westsider Avatar asked Nov 08 '10 00:11

westsider


People also ask

How to use observe in Swift?

When you create an observer, you start observation by calling the observe(_:options:changeHandler:) method with a key path that refers to the property you want to observe. You use the oldValue and newValue properties of the NSKeyValueObservedChange instance to see what's changed about the property you're observing.

What is KVO key-value observation?

KVO, which stands for Key-Value Observing, is one of the techniques for observing the program state changes available in Objective-C and Swift. The concept is simple: when we have an object with some instance variables, KVO allows other objects to establish surveillance on changes for any of those instance variables.

What is property observation in Swift?

Property observers observe and respond to changes in a property's value. Property observers are called every time a property's value is set, even if the new value is the same as the property's current value. You can add property observers in the following places: Stored properties that you define.

What is KVO and KVC in Swift?

KVO and KVC or Key-Value Observing and Key-Value Coding are mechanisms originally built and provided by Objective-C that allows us to locate and interact with the underlying properties of a class that inherits NSObject at runtime.


1 Answers

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.

like image 94
Marcus S. Zarra Avatar answered Sep 28 '22 01:09

Marcus S. Zarra