kvo infusion español iphone key-value-observing nsexception

iphone - infusion - Un mensaje-observeValueForKeyPath: ofObject: change: context: se recibió pero no se manejó



kvo español (4)

Soy relativamente nuevo en KVO, por lo que es muy probable que esté violando alguna regla fundamental. Estoy usando Core Data.

Mi aplicación falla con el siguiente mensaje: Y lo que no entiendo es por qué un CGImage se involucra en la observación de un valor establecido en un objeto 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”.

Todo lo que está sucediendo para desencadenar esto es:

[[self measurementPointer] setMeasurementDescriptor:descriptor];

Dado este,

[[meterDisplay measurementPointer] addObserver:self forKeyPath:@"measurementDescriptor" options:NSKeyValueObservingOptionNew context:nil];

Básicamente, los objetos MeasurementPointer apuntan a objetos MeasurementDescriptor, y ambos son subclases NSManagedObject. Los objetos MeasurementDescriptor describen una combinación específica de ''medida'' y ''unidad'' (por ejemplo, "Temperatura (° C)" o "Velocidad del viento (mph)"). Los MeasurementDescriptors son algo así como singletons en la medida en que solo hay uno para cada combo único de unidades de medida.

Otros objetos hacen referencia a los MeasurementPointers, tanto los objetos Model como los objetos Controller. Un MeasurementPointer hace referencia a un MeasurementDescriptor. Muchos objetos están interesados ​​en saber cuándo un MeasurementPointer comienza a hacer referencia a un MeasurementDescriptor nuevo / diferente. Un cambio de este tipo podría hacer que el eje de la visualización de un gráfico cambie, por ejemplo. O, en el código anterior, puede hacer que la pantalla del medidor muestre una muestra diferente (de un conjunto seleccionado de muestras).

Creo que el problema fundamental es que un CGImage está recibiendo un mensaje que no está destinado a él ... desafortunadamente, esto es intermitente, por lo que no he podido encontrar un patrón que lo active.


Me encontré con este problema al pasar accidentalmente el objetivo como el observador (en lugar de uno mismo) de esta manera:

[self.someView addObserver:self.someView forKeyPath:@"key" options:0 context:nil];

El mensaje de error no sirvió de nada para identificarlo, así que solo pensé en publicar en caso de que alguien más haga lo mismo.


Tuve el mismo problema, pero en mi caso estaba observando un contexto diferente. Luego puse todo en el mismo contexto y el accidente desapareció. Espero que esto ayude a alguien.


Usted tiene un objeto que fue desalojado y no dejó de observar otro objeto. Recorra todas las llamadas de -addObserver... y asegúrese de que -removeObserver... con las llamadas -removeObserver... al menos en -dealloc y posiblemente en -viewDidUnload según la estructura de su aplicación.


Vi este error cuando envié el método observeValueForKeyPath a super , que no había registrado como observador del cambio. Los documentos de Apple dicen "Asegúrese de llamar a la implementación de la superclase [de observeValueForKeyPath ] si la implementa ".

Mi solución fue cambiar:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if ([keyPath isEqualToString:kPropertyThatChanges]) { ... } [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; }

a:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if ([keyPath isEqualToString:kPropertyThatChanges]) { ... } }