2014-01-20 3 views
0

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

В качестве примера, если я хочу, чтобы удалить объект из контекста, как это:

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    NSManagedObjectContext *context = [self managedObjectContext]; 
    if (editingStyle == UITableViewCellEditingStyleDelete) 
    { 
     // Delete object from database 
     [context deleteObject:[self.tests objectAtIndex:indexPath.row]]; 
     NSError *error = nil; 
     if (![context save:&error]) { 
      NSLog(@"Can't Delete! %@ %@", error, [error localizedDescription]); 
      return; 
     } 
     [self.tests removeObjectAtIndex:indexPath.row]; 
     [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
    } 
} 

Это работает, но когда данные большие, [context save:&error] занимает много времени, так как я могу сделать это в фоновом режиме? Кажется, что я не могу работать с другим контекстом, иначе я получаю ошибку an nsmanagedobjectcontext cannot delete objects in other contexts. Я пробовал сотни разных вещей, но я потерялся ... Спасибо!

ответ

0

Ознакомьтесь с методами performBlock и performBlockAndWait в NSManagedObjectContext.

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

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    NSManagedObjectContext *context = [self managedObjectContext]; 
    if (editingStyle == UITableViewCellEditingStyleDelete) 
    { 
     NSManagedObject *m = [self.tests objectAtIndex:indexPath.row]; 
     [context performBlock:^{ 
      [context deleteObject:m]; 

      if (![context save:&error]) { 
       //Note: You should really do something more useful than log this 
       NSLog(@"Can't Delete! %@ %@", error, [error localizedDescription]); 
      } 
     }]; 
     [self.tests removeObjectAtIndex:indexPath.row]; 
     [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
    } 
} 

performBlock вызов асинхронным (в отличие от его синхронного аналога performBlockAndWait), которая позволит обновлять Tableview действовать в зависимости от контекста занят сохранение в отдельном потоке.

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

+0

Спасибо! это похоже на работу. Мне просто интересно: можно ли использовать только NSPrivateQueueConcurrencyType? – jcr

+0

до тех пор, пока вы используете executeBlock/perfomBlockAndWait для чтения из управляемых объектов, это нормально. Экземпляр табличного вида становится немного неудобным, потому что вы должны скопировать значения из вызова executeBlockAndWait, чтобы установить их в ячейке. Начните с NSMainQueueConcurrencyType (чтобы вы могли установить свойства ячейки в блоке), а затем переходите к частной очереди, если это имеет смысл. – ImHuntingWabbits

1

Вы можете удалить только object в context; в котором вы выбрали этот управляемый объект. Если вы используете seprate thread с новым контекстом, в этом случае вы должны получить objectId от managedObject вы получили от первого контекста, так что вы можете удалить объект

[context objectWithID:objectId]]; 

NSManagedObjectID такой же между контекстами, но сам NSManagedObject не является.

+1

(1) Предполагая, что управляемый объект находится в постоянном хранилище –

+0

Любая операция crud будет выполнена в контексте ... –

1

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

Вам следует избегать дорогостоящих операций в любом вызове с использованием интерфейса пользовательского интерфейса, подобном этому. Нет причин для сохранения сразу после удаления. Сохраните позже, сохраните, когда пользователь ожидает задержки в пользовательском интерфейсе. Core Data будет отлично работать без сохранения.

 Смежные вопросы

  • Нет связанных вопросов^_^