An-observeValueForKeyPath: ofObject: change: context: сообщение получено, но не обработано



Я относительно новичок в кво, так что есть хороший шанс, что я нарушаю какое-то фундаментальное правило. Я использую основные данные.



Мое приложение аварийно завершает работу со следующим сообщением: и я не могу понять, почему 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)" или "скорости ветра (миль / ч)"). MeasurementDescriptors являются чем-то вроде синглетов в той степени, что существует только один для каждой уникальной комбинации единиц измерения.



MeasurementPointers ссылаются на другие объекты-как объекты модели, так и объекты контроллера. MeasurementPointer ссылается на MeasurementDescriptor. Многие объекты являются интересно знать, когда MeasurementPointer начинает ссылаться на новый / другой MeasurementDescriptor. Например, такое изменение может привести к изменению оси отображения графика. Или, в приведенном выше коде, может вызвать отображение на дисплее счетчика другого образца (из выбранного набора образцов).



Я думаю, что фундаментальная проблема заключается в том, что CGImage получает сообщение, которое не предназначено для него... к сожалению, это прерывистый процесс, поэтому я не смог найти закономерность, которая вызвать его.
542   4  

4 ответов:

У вас есть объект, который освободился и не перестал наблюдать за другим объектом. Просмотрите все ваши вызовы -addObserver... и убедитесь, что они совпадают с вызовами -removeObserver... по крайней мере в -dealloc и, возможно, в -viewDidUnload в зависимости от структуры вашего приложения.

Я увидел эту ошибку, когда отправил Метод observeValueForKeyPath в super, который я не зарегистрировал как наблюдатель за изменением. Apple docs говорят: "обязательно вызовите реализацию суперкласса [из observeValueForKeyPath] если он реализует его ."

Мое решение было изменено:

- (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];
}

Кому:

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

Я столкнулся с этой проблемой, случайно пропустив цель в качестве наблюдателя (вместо себя), как это:

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

Сообщение об ошибке было совсем не полезно для идентификации этого, поэтому я просто подумал, что отправлю сообщение на случай, если кто-то еще сделает то же самое.

У меня была та же проблема, но в моем случае я наблюдал другой контекст. Затем я поставил все в тот же контекст, и авария исчезла. Надеюсь, это кому-то поможет.

Comments

    Ничего не найдено.