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

Основные данные: УДАЛИТЬ ГДЕ

Я знаю, как использовать NSPredicate для выполнения SQL SELECT -подобной операции. Как я могу выполнить что-то вроде DELETE WHERE? Нужно ли мне называть [NSManagedObjectContext deleteObject] для каждого извлеченного объекта? Благодаря

NSError *error;

NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:TASK_ENTITY inManagedObjectContext:managedObjectContext]];

NSPredicate *predicate = [NSPredicate predicateWithFormat: @"label LIKE  %@", label];
[request setPredicate:predicate];

NSArray *array = [managedObjectContext executeFetchRequest:request error:&error];

[managedObjectContext deleteObject:[array objectAtIndex:0]];
4b9b3361

Ответ 1

Я считаю, что цикл по возвращенному массиву и вызов [NSManagedObjectContext deleteObject:] - это "правильный" /идиоматический способ сделать это. Это может показаться неэффективным, но помните, что команда fetch фактически не извлекает данные объектов, а метод deleteObject: просто отмечает объект для удаления, который применяется при отправке [NSManagedObjectContext save:]. Не зная внутренних данных Core Data, я не могу сказать вам, насколько он эффективен, как запрос DELETE WHERE (предположительно, Core Data имеет индексированные первичные ключи в памяти из выборки и использует их), но в моем опыте с профилированием Core Data приложений он не значительно медленнее, чем сохранение новых или обновленных объектов.

Ответ 2

Я не нашел другого способа, чем использовать метод NSArray для удаления.
(Если есть, я хочу знать об этом)
Вы можете вложить вызов, чтобы иметь его на одной строке, если вы действительно не хотите хранить массив. Но если вы это сделаете, проверьте, что такое возврат Fetch в случае ошибки.

makeObjectsPerformSelector:
Отправляет каждому объекту в массиве сообщение, идентифицированное данным селектором, начиная с первого объекта и продолжая через массив до последнего объекта.
    - (void) makeObjectsPerformSelector: (SEL) aSelector

Или есть блок, который должен быть быстрее.

Ответ 3

NSFetchRequest * fetchRequest = [[NSFetchRequest alloc] init];  [fetchRequest setEntity: [NSEntityDescription entityForName: TASK_ENTITY inManagedObjectContext: managedObjectContext];

[fetchRequest setPredicate: [NSPredicate predicateWithFormat: @ "label LIKE% @", label.text]];

NSError * error = nil;

NSArray* results = [managedObjectContext executeFetchRequest:fetchRequest error:&error];

if(![results count]==0)
{
   [managedObjectContext deleteObject:[results objectAtIndex:0]];
}
if (![managedObjectContext save:&error]) {
    NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);
}

Ответ 4

Я просто попробовал это и успешно:

NSError *error = nil;
NSFetchRequest* fetchrequest = [NSFetchRequest fetchRequestWithEntityName:@"EntityName"];
[request setPredicate:[NSPredicate predicateWithFormat:@"attribute == %@", variable]];
NSArray *deleteArray = [context executeFetchRequest:fetchrequest error:&error];

if (deleteArray != nil)
{
    for (NSManagedObject* object in deleteArray)
    {
        [context deleteObject:object];

        //Reload/refresh table or whatever view..
    }

    [context save:&error];
}

Ответ 5

Вы можете использовать NSBatchDeleteRequest, доступный в iOS 9.0+, macOS 10.11+, tvOS 9.0+, watchOS 2.0+

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"label LIKE  %@", label];
NSFetchRequest *fetchRequest = [TaskEntity fetchRequest];
[fetchRequest setPredicate:predicate];
// Create batch delete request
NSBatchDeleteRequest *deleteReq = [[NSBatchDeleteRequest alloc] initWithFetchRequest:fetchRequest];
NSError *error = nil;
NSBatchDeleteResult *deletedResult = [appDelegate.persistentContainer.viewContext executeRequest:deleteReq error:&error];
if (error) {
  NSLog(@"Unable to delete the data");
}
else {
  NSLog(@"%@ deleted", deleteReq.result);
}

Код Swift (из приведенной выше ссылки)

let fetch = NSFetchRequest<NSFetchRequestResult>(entityName: "Employee")
fetch.predicate = NSPredicate(format: "terminationDate < %@", NSDate())
let request = NSBatchDeleteRequest(fetchRequest: fetch)

do {
    let result = try moc.execute(request)
} catch {
    fatalError("Failed to execute request: \(error)")
}

Примечание:

Я нашел ниже комментарий о execute of moc

Способ передачи запроса в хранилище без влияния на содержимое контекста управляемого объекта.

Это означает, что любые несохраненные данные в moc не будут затронуты. т.е. если вы создали/обновили объект, который попадает в критерии запроса на удаление и не вызывается save на moc, то этот объект не будет удален.