Подтвердить что ты не робот

Coredata - "NSObjectInaccessibleException - CoreData не может выполнить ошибку"

Я новичок в данных Core и все еще разбираюсь в гайках и болтах, и эта ошибка вызывает у меня часами, и я не могу найти решение. Любая помощь приветствуется.

Проблема такая:

У меня есть два представления, которые извлекают данные с сервера и обновляют пользовательский интерфейс. Я создал поток таким образом

view1 → Отправить HTTP Req с сервера - Получить обратный вызов → Сохранить данные в Coredata → Чтение из основных данных и отображение в пользовательском интерфейсе (обратный вызов и сохранение/чтение Coredata происходят в ViewController)

view2 → Отправить HTTP Req с сервера - Получить обратный вызов → Сохранить данные в Coredata → Чтение из основных данных и отображение в пользовательском интерфейсе (обратный вызов и сохранение/чтение Coredata происходят в ViewController)

Просмотр 2 повторяет этот процесс каждые 3 секунды, поскольку это автоматический экран обновления.

Проблема заключается в том, что всякий раз, когда я пытаюсь переключаться между представлениями 1 и 2 очень быстро, это приводит к сбою приложения с ошибкой выше. Если я ожидаю несколько секунд в каждом представлении (дождаться получения данных с сервера), он отлично работает. Я что-то не так, что мне нужно изменить?

- (void) refreshData {
    [super refreshData];
    [[UserDataFactory sharedSingleton] refreshLoggedInUserDataAndRespondTo:self user:self.user];
}

- (BOOL) refreshDataCallback:(QExtendedHTTPOperation*)responseOperation {
    [self saveToCoreData: responseOperation.responseArray];
    NSMutableArray *tmp = [[NSMutableArray alloc] initWithArray:[self readFromCoreData]];
    [self setData: tmp];
    [tmp release];
    [self.tableView reloadData];
    return YES;
}

- (void) saveToCoreData:(NSArray *) responseArray{
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"CoreView1" inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:entity];
    [fetchRequest setReturnsObjectsAsFaults:NO];
    NSError *error;
    NSArray *items = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
    [fetchRequest release];

    for (NSManagedObject *managedObject in items) {
            [self.managedObjectContext deleteObject:managedObject];
    }

    for (int i=0; i<[responseArray count]; i++) {
            CoreView1 *coreView1_ = [NSEntityDescription insertNewObjectForEntityForName:@"CoreView1" inManagedObjectContext:self.managedObjectContext];
            coreView_.id = [[responseArray objectAtIndex:i] id];    
            [self.managedObjectContext insertObject:coreView1_];
    }
    [self saveContext:self.managedObjectContext];
}

- (NSArray *) readFromCoreData{ 
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"CoreView1" inManagedObjectContext:self.managedObjectContext];
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    [fetchRequest setEntity:entity];
    [fetchRequest setReturnsObjectsAsFaults:NO];
    NSError *error;
    NSMutableArray *fetchedObjects = [[self.managedObjectContext executeFetchRequest:fetchRequest error:&error] mutableCopy];
    [fetchRequest release];
    return [fetchedObjects autorelease];
}

Это пример кода, который я использую, даже View2 имеет те же обратные вызовы и следует за тем же потоком.

Изменить 1 Забыл упомянуть об этом ранее, я всегда получаю ошибку в методе saveToCoreData. Кроме того, еще одно замечание: если я удалю код для удаления объектов, все работает отлично (мне нужно удалить все существующие данные из таблицы, прежде чем сохранять обновленные данные). Не уверен, что происходит, хотя.

4b9b3361

Ответ 1

Причина удаления вашего кода удаления заставляет его работать, потому что вы удаляете данные в постоянном хранилище, не обновляя другое представление, которое все еще управляло экземплярами объектов, привязанными к этим данным, все еще находящимся в памяти. Помните, что в то время как Core Data имеет дело с объектами, каждый объект должен иметь строку в базе данных позади нее. Когда вы удаляете эту строку, Core Data сердится.

Итак, чтобы исправить эту проблему и все еще удалить свои данные, вы должны иметь свои представления для прослушивания уведомлений NSManagedObjectContextWillSaveNotification и/или NSManagedObjectContextDidSaveNotification и обновлять свои представления с помощью самых последних версий данных в вашем магазине. Именно в этот момент вы должны выбросить любые объекты Core Data, которые ваши представления удерживают, и перезагрузить их из хранилища.

Ответ 2

Я только что решил эту ошибку в моем коде. Кажется, мой кеш был поврежден каким-то образом. Я использовал Кристофер Пикслей и Кейл Гиллард, предлагая удалить или переименовать мой кеш, и вуаля. Индекс NSFetchedResultsController за пределами границ

Ответ 3

Для информации, вчера, у меня была такая же ошибка. Я проверил в живой версии приложения, и он все еще был там. Хлоп.

Я просмотрел все перестановки добавления информации в основной стек данных до тех пор, пока не произошел сбой.

Затем я просмотрел файл sqlite из приложения в библиотеке симулятора, используя SqliteManager. Я обнаружил ошибку данных в одной таблице. Это произошло, поскольку при первом запуске приложения был использован стартер db. Ошибка была в стартере db.

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

Ответ 4

Вы высвобождаете fetchedObjects в свой метод readFromCoreData​​strong > . executeFetchRequest в любом случае вернет вам автореализованные объекты. Когда текущий цикл цикла завершается (когда вы переходите из представлений), он пытается дважды выпускать объекты (при условии, что вы не использовали свои собственные пулы автозапуска).

Я бы изменил

return [fetchedObjects autorelease]; 

к

return fetchedObjects;