Я думаю, что этот вопрос довольно прост и распространен, но я до сих пор не понимаю, почему он не работает. Позвольте мне разоблачить контекст:KVO и основные данные - управляемый объект самообслуживания
Предположим, у меня хорошая модель данных ядра с объектом под названием Document. Этот документ имеет тип, дата, номер и версию ... Например, Тип: D Дата: 17-10-2015, номер: и версия . Этот документ имеет и идентификатор, рассчитанный с этими четырьмя значениями: D20151017-24-R03.
Будет много этих документов, и мне придется искать их по его Идентификатору, и я также буду использовать много NSFetchedResultsController
. Таким образом, преходящая возможность прямо.
Вот что я сделал. Первый регистр для наблюдения четырех связанных атрибутов:
- (instancetype)initWithEntity:(NSEntityDescription *)entity insertIntoManagedObjectContext:(NSManagedObjectContext *)context {
self = [super initWithEntity:entity insertIntoManagedObjectContext:context];
if (self) {
[self addObserver:self forKeyPath:_Property(documentTypeRaw) options:0 context:KVODocumentIdContext];
[self addObserver:self forKeyPath:_Property(date) options:0 context:KVODocumentIdContext];
[self addObserver:self forKeyPath:_Property(number) options:0 context:KVODocumentIdContext];
[self addObserver:self forKeyPath:_Property(version) options:0 context:KVODocumentIdContext];
}
return self;
}
Затем разрегистрировать когда высвобождено:
- (void)dealloc {
[self removeObserver:self forKeyPath:_Property(documentTypeRaw) context:KVODocumentIdContext];
[self removeObserver:self forKeyPath:_Property(date) context:KVODocumentIdContext];
[self removeObserver:self forKeyPath:_Property(number) context:KVODocumentIdContext];
[self removeObserver:self forKeyPath:_Property(version) context:KVODocumentIdContext];
}
И наконец, удался уведомление:
- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if (context == KVODocumentIdContext) {
[self updateDocumentId];
}
else {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}
Только здесь updateDocumentId
:
- (void) updateDocumentId {
NSString * prefix = [self documentTypePrefix:self.documentTypeRaw];
NSString * date = [self.date documentIdFormat];
NSString * number = [NSString stringWithFormat:@"%.2d",[self.number shortValue]];
NSString * version = [self.version isEqualToNumber:@0][email protected]"":[NSString stringWithFormat:@"-R%.2d",[self.version shortValue]];
self.documentId = [NSString stringWithFormat:@"%@%@-%@%@",prefix,date,number,version];
}
Для меня это должно было сработать идеально ... Но ... Это не ...
У меня есть хороший:
failed: caught "NSInternalInconsistencyException", "<MBSDocument: 0x7fd9dbb45f40> (entity: MBSDocument; id: 0x7fd9dbb3cd00 <x-coredata:///MBSDocument/tB55CB581-AEC0-4211-A78A-7C48377BACC2612> ; data:
...
An -observeValueForKeyPath:ofObject:change:context: message was received but not handled.
Key path: date
Observed object: <MBSDocument: 0x7fd9dbb45f40> (entity: MBSDocument; id: 0x7fd9dbb3cd00 <x-coredata:///MBSDocument/tB55CB581-AEC0-4211-A78A-7C48377BACC2612> ; data:
...
Я пробовал много вещей, в том числе удаление вызова до super
в observeValueForKeyPath:ofObject:change:context:
, или регистрироваться в init
и т. д. Но ничего не получилось. Ну, некоторая помощь будет принята с благодарностью.
Заранее спасибо.
Edit: Это как определяется контекст:
static void * KVODocumentIdContext = &KVODocumentIdContext;
Edit 2: Класс документа наследует от NSManagedObject
.
Как вы использовали контекст для наблюдения. Похоже, что наблюдательный контекст как-то отличается. – Sandeep
В соответствии с http://nshipster.com/key-value-observing/#correct-context-declarations я объявил контекст таким же образом (я отредактировал сообщение) – Zaphod