NSArrayController и Core Data ведут себя не так, как ожидалось

#objective-c #cocoa #core-data #nsarraycontroller

#objective-c #cocoa #core-data #nsarraycontroller

Вопрос:

У меня есть окно со списком, полным объектов Core Data, и окно отображения, которое открывается при выборе одного из них.

Определенное действие в окне отображения помечает объекты Core Data как «Прочитанные».

Чтобы открыть объект, я передаю объект в окно отображения, а также sortDescriptors и filterPredicate, которые отображали список, поэтому окно отображения может перемещаться вперед / назад (в главном окне иногда отображается подмножество объектов, вот почему мне нужны sortDescriptors и filterPredicate).

Пометка открытого объекта как прочитанного работает отлично. Он обновляется в главном окне автоматически благодаря KVO.

Однако, когда я перехожу вперед / назад к другому объекту в окне отображения, пометка как прочитанный больше не работает. Я просматриваю код и вижу, что код выполняется, проверяю новое значение, и оно помечено как прочитанное — но это не отражается ни в главном окне, ни в базе данных.

Есть ли что-нибудь очевидное, что могло быть причиной этого? Я ни в коем случае не создаю копию объекта core data. Окно отображения использует NSArrayController для извлечения данных, и к нему применяются sortDescriptors и filterPredicate. Мой код для получения следующего объекта выглядит следующим образом:

 -(MyObject *object)nextObject {

    // _object is the object being displayed by the display window.
    // _listContainingObject is an NSArrayController set to Entity: Object

    NSArray *list = [_listContainingObject arrangedObjects];

    NSUInteger positionInList = 0;
    for (MyObject *object in list) {

        if ([[[object objectID] URIRepresentation] isEqualTo: [[_object objectID] URIRepresentation]]) {            break;
        }
        positionInList  ;
    }

    if (positionInList == [list count] - 1) return nil;

    if (positionInList   1 > [list count] - 1) return nil;

    MyObject *object = [list objectAtIndex: positionInList   1];

    return object;    

}
  

Действительно кажется, что я сталкиваюсь с какой-то скрытой ошибкой Core Data, например, объекты, извлеченные из другого NSArrayController, являются копиями… но все выполняется с того же managedObjectContext. Контекст управляемого объекта NSArrayController привязан к свойству делегата моего приложения, которое возвращает тот же контекст, который используется всеми остальными. Я довольно сильно ломаю голову над этим.

Ответ №1:

помните, что когда вы работаете с элементами, ваш managedObjectContext действует как блокнот для записи. Ваши изменения в управляемых объектах не будут отражены в базе данных, пока вы фактически не сохраните контекст управляемого объекта.

Итак, после того, как вы пометите элемент как прочитанный или непрочитанный, вам нужно сохранить контекст.

 NSError *saveContextError=nil;
if (![yourManagedObjectContext save:amp;saveContextError){
    // Handle the error
    NSLog(@"managedObjectContext save error:  %@",error);
}
  

Комментарии:

1. К сожалению, это не так — я сохраняю каждый раз, когда вносятся изменения.

2. Я принял это как правильное, потому что это было достаточно близко — оказалось, что по какой-то причине я работал с другим контекстом управляемого объекта, несмотря на то, что делегат приложения возвращал тот же объект. Все еще очень шатко, но, похоже, сейчас это работает.