从managedObjectContext&删除NSManagedObject。的tableView

时间:2015-04-17 19:03:05

标签: ios objective-c uitableview core-data

我有UITableView,显示使用array创建的NSFetchRequest实体的属性。我的导师告诉我,为了我的目的,我不需要fetchedResultsController - 所以我不需要在我的{NSFetchedResultsControllerDelegate 方法中添加UITableViewController {1}}课程。他的比喻是将一辆保时捷发动机装进大众甲壳虫。

我的tableView有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];
}

更新

以下是代码在最终工作时的样子:

// 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 个答案:

答案 0 :(得分:1)

可能您的tableView数据源方法使用self.locationCaregories。如果是这样,问题是您没有从该数组中删除相关的Category(尽管您从managedObjectContext中删除它,它仍然在数组中)。

现在,由于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所说,移动代码将行删除到方法的末尾 - 在更新表之前,应该正确地获取数据。