2015-04-17 3 views
0

У меня есть UITableView, который отображает атрибуты объектов, которые находятся в array, созданных с помощью NSFetchRequest. Мой инструктор говорит мне о моих целях, я НЕ нужен fetchedResultsController --so Мне не нужно добавлять NSFetchedResultsControllerDelegate методам в мой класс UITableViewController. Его аналогия заключалась в установке двигателя Porsche в VW Beetle.Удалить NSManagedObject из managedObjectContext & tableView

В моем столеView есть 2 секции (0 и 1). Все работает нормально, пока я не попытаюсь удалить объекты из раздела 1 (раздел 0 является статическим).

С этим commitEditingStyle код, приложение не падает с его ошибкой:

*** Assertion failure in -[UITableView _endCellAnimationsWithContext:], 
/SourceCache/UIKit_Sim/UIKit-3347.40/UITableView.m:1623 

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { 

    if (editingStyle == UITableViewCellEditingStyleDelete && indexPath.section == 1) { 
     // Delete cell 
     [tableView beginUpdates]; 
     [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
     [tableView endUpdates]; 


     // Delete LocationCategory from managedObjectContext 
     LocationCategory *categoryToDelete = [self.locationCategories objectAtIndex:indexPath.row]; 
     [self.managedObjectContext deleteObject:categoryToDelete]; 
     [self.managedObjectContext save:nil]; 

    } else if (editingStyle == UITableViewCellEditingStyleInsert) { 
     // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view 
    } 
} 

Когда я перезапустить приложение, то locationCategory (мой NSManagedObject) больше не в managedObjectContext. Я знаю, что у меня проблема с обновлением tableView, но я не знаю, как ее разрешить. Я выкопался, попробовал кучу перспективных решений, но ничто не решает проблему.

Вот как создается мой массив:

- (void)viewWillAppear:(BOOL)animated { 
    [super viewWillAppear:animated]; 

    self.title = @"Select a Category"; 

    // Core Data 
    AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication]delegate]; 
    self.managedObjectContext = [appDelegate managedObjectContext]; 

    // Fetch LocationCategories & dump them in an array 
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
    [fetchRequest setEntity:[NSEntityDescription entityForName:@"LocationCategory" inManagedObjectContext:self.managedObjectContext]]; 
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"categoryName" ascending:YES]; 

    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:&sortDescriptor count:1]; 
    [fetchRequest setSortDescriptors:sortDescriptors]; 

    NSArray *categories = [self.managedObjectContext executeFetchRequest:fetchRequest error:nil]; 
    self.locationCategories = categories; 

    [self.tableView reloadData]; 
} 

Update:

Вот что код выглядел в конце, когда он работал:

// This was previously an NSArray. It needs to be an NSMutableArray 
@property (nonatomic, strong) NSMutableArray *locationCategories; 

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { 
    if (editingStyle == UITableViewCellEditingStyleDelete && indexPath.section == 1) { 
     // Delete LocationCategory from managedObjectContext 
     LocationCategory *categoryToDelete = [self.locationCategories objectAtIndex:indexPath.row]; 
     [self.managedObjectContext deleteObject:categoryToDelete]; 
     [self.locationCategories removeObjectAtIndex:indexPath.row]; 
     [self.managedObjectContext save:nil]; 


     // Delete cell 
     [tableView beginUpdates]; 
     [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
     [tableView endUpdates]; 

    } else if (editingStyle == UITableViewCellEditingStyleInsert) { 
     // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view 
    } 
} 
+1

Вы пытаетесь изменить заказ? сначала удаляем и сохраняем, а '[tableView beginUpdates]' – thorb65

+0

Просто попытался изменить порядок удаленных вещей. 'managedObjectContext', а затем' tableView' без везения. Я также попытался поставить '[tableView beginUpdates]' сначала в методе и '[tableView endUpdates]' в конце метода (вне оператора 'if'). Я сбой с той же ошибкой в ​​'[tableView endUpdates]'. – Adrian

ответ

1

Предположительно ваш Tableview DataSource методы используют self.locationCaregories. Если это так, проблема заключается в том, что вы не удаляете соответствующий Category из этого массива (хотя вы удаляете его из управляемого объекта ObjectContext, он остается в массиве).

Теперь, поскольку self.locationCategories является NSArray, это неизменный, поэтому вы не можете просто удалить соответствующий элемент. Вы можете повторно выполнить выборку сразу после удаления объекта, но это кажется немного неэффективным. Вместо этого я рекомендую сделать self.locationCategories NSMutableArray. Вам нужно будет изменить определение свойства, а также линия в viewWillAppear где вы первый установить его:

NSArray *categories = [self.managedObjectContext executeFetchRequest:fetchRequest error:nil]; 
    self.locationCategories = [categories mutableCopy]; 

Затем в методе commitEditingStyle, вы можете удалить соответствующий объект из массива:

LocationCategory *categoryToDelete = [self.locationCategories objectAtIndex:indexPath.row]; 
    [self.locationCategories removeObjectAtIndex:indexPath.row]; 

И как говорит thorb65, переместите код, чтобы удалить строки до конца метода - вы должны получить данные правильно, прежде чем обновлять таблицу.

+0

Спасибо @ thorb65 и @pbasdf за ваши ответы. Между вашими ответами я получил эту работу. Я думаю, что «NSArray» был частью проблемы. Решения, упомянутые здесь, не заставили его работать самостоятельно, но из отчаяния я взял некоторый код из 'viewWillAppear' и воссоздал' self.locationCategories' после того, как элемент был удален из 'managedObjectContext'.Спасибо вам за вашу помощь в этом. – Adrian

+0

Перечитайте и обновите код, описанный как @pbasdf, намного чище и намного короче. Еще раз спасибо! – Adrian

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