deleteObject удаляет, но оставляет пустые строки в базе данных sqlite3? - PullRequest
0 голосов
/ 24 сентября 2011

Мне нужно удалить выбранную строку базы данных, показанную в updatePick, но, похоже, не получается получить managedObject, который должен быть в строке [context deleteObject:managedObject]; правильно. Вот метод deleteUpdate:

-(void)deleteUpdate {
    NSLog(@"35-Delete pressed.");
    NSManagedObjectContext *context = [self managedObjectContext];
    NSEntityDescription *updateEntity = [NSEntityDescription entityForName:@"Updates" inManagedObjectContext:context];

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    [fetchRequest setEntity:updateEntity];

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(dateGains = %@)", [arrayNSDateGains objectAtIndex:updatePick]];
    [fetchRequest setPredicate:predicate];

    NSArray *gains = [context executeFetchRequest:fetchRequest error:nil];

    for (updateGains in gains) {
        [context deleteObject:updateGains];
    }
    [self saveContext];
}

Это удаляет содержимое строки в базе данных (YEAH), за исключением того, что оставляет пустую строку и три остаточных элемента: первичный ключ (Z_PK) и два целых числа (Z_ENT) & (Z_OPT). Пустая строка вызывает ошибки в другом месте. Что мне здесь не хватает?

Ответы [ 2 ]

3 голосов
/ 25 сентября 2011

Базовые данные после удаления часто оставляют пустые строки в хранилищах sqlite.В документации прямо указывается, что файл хранилища не будет уменьшаться после удаления до тех пор, пока в какой-то произвольной точке постоянный объект хранилища не решит сжать хранилище.Базовые данные не являются SQL.Сущности не являются таблицами.Объекты не являются строками.Атрибуты не являются столбцами.Отношения не объединяются.Базовые данные - это система управления графом объектов, которая может сохранять или не сохранять объектный граф, а может и не использовать SQL для этого далеко за кулисами.Попытка представить базовые данные в терминах SQL приведет к тому, что вы полностью неправильно поймете базовые данные и приведет к большим трудностям и потерянному времени.

Базовые данные просто имеют возможность сериализации (сублимационной сушки) объекта в хранилище sqlite.Однако то, как это происходит, не документировано, поэтому, глядя на хранилище sqlite напрямую, вы многое не скажете.

Единственный способ подтвердить, что объект был удален, - это получить и сохранить его постоянный managedObjectID.После удаления попросите persistentStoreCoordinator извлечь объект для идентификатора с objectWithID:.Если объект был удален, он не найдет его.

Существует только несколько способов, которыми объект может остаться после удаления.Менеджер отмены может откатить очевидные удаления, но здесь это не так.Если вы сохраните управляемый объект в другом месте, то объект в памяти останется после удаления (хотя он не будет отображаться в операциях с базовыми данными, как при извлечении.)по вопросу с магазином.Такие проблемы очень редки.

Обновление:

После сохранения я делаю [self setNeedsDisplay];который вызывает перерисовку гистограммы на основе данных в базе данных.Первый изменяемый массив пытается вставить insertObject: atIndex: объект nil, вызывающий сбой… Я вставил if (dateGained == nil) continue;в тот момент, когда произошла следующая ошибка, и она прекрасно работает.

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

Например: у вас есть таблица, в которой отображается один Update объект на строку.При запуске контроллер пользовательского интерфейса извлекает все существующие Update объекты.Это говорит таблице, что у нее есть [fetchObjects count].Затем вы удаляете некоторые из объектов Update, но затем не говорите таблице, что теперь в ней меньше строк.Таблица будет пытаться получить доступ к объектам в массиве после последнего элемента, который вызывает сбой.

Решение здесь состоит в том, чтобы зарегистрировать контроллер для уведомления контекста:

NSManagedObjectContextObjectsDidChangeNotification

… и затем обновить массив и количество строк таблиц перед вызовом [self setNeedsDisplay]. После этого таблица поймет, сколько строк в ней должно быть.

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

0 голосов
/ 24 сентября 2011

Вы забыли получить объект. Сделайте это:

NSArray *results = [context executeFetchRequest:request error:nil];
if (results) {
   for (NSManagedObject *updateGains in results) {
      [context deleteObject:updateGains];
   }
[context save:nil];
}

[self saveContext];

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...