ios - 删除记录时出错,由于未捕获的异常而终止应用程序 'NSInternalInconsistencyException'

标签 ios objective-c xcode core-data uitableview

我想从我的 tableviewcontroller 单元格中删除记录。

代码对我来说似乎很好,当我按一行删除时出现异常......

这是我的 ViewController.h 文件代码

#import <UIKit/UIKit.h>

@interface IMSCategoryViewController : UITableViewController
@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
@property(nonatomic,retain)NSArray *arr;
@property (readonly, strong, nonatomic) NSMutableArray *categoryArray;
@end

这个在实现文件中。

#import "IMSCategoryViewController.h"
#import "IMSAppDelegate.h"
#import "Category.h"

@interface IMSCategoryViewController ()
{
    NSManagedObjectContext *context;
}
@end

@implementation IMSCategoryViewController
@synthesize managedObjectContext = _managedObjectContext;
@synthesize managedObjectModel = _managedObjectModel;
@synthesize persistentStoreCoordinator = _persistentStoreCoordinator;
@synthesize categoryArray;
@synthesize arr;

- (void)viewDidLoad
{
    [super viewDidLoad];

    //    [self.tableView reloadData];

    IMSAppDelegate *appDelegate = [[UIApplication sharedApplication]delegate];

    context = [appDelegate managedObjectContext];

    NSEntityDescription *category = [NSEntityDescription entityForName:@"Category" inManagedObjectContext:context];

    NSFetchRequest *request = [[NSFetchRequest alloc] init];

    [request setEntity:category];

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"is_active == 1"];

    [request setPredicate:predicate];

    [request setFetchBatchSize:25];


    [request setEntity:category];

    NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];

    NSArray *srotDesc = [[NSArray alloc]initWithObjects:sort, nil];

    [request setSortDescriptors:srotDesc];

    NSError *error;

    NSMutableArray *results = [[context executeFetchRequest:request error:&error] mutableCopy];

    if (results == nil) {

        //error handle here
    }

    [self setArr:results];

    NSLog(@"there is category array");

    [self.tableView reloadData];


    [self.arr count];

    }


- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{

    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{

    return [self.arr count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    Category *category = [self.arr objectAtIndex:indexPath.row];

    // Configure the cell...
    cell.textLabel.text = [category name];

    cell.detailTextLabel.text = [category descript];

    return cell;
}


// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Return NO if you do not want the specified item to be editable.
    return YES;
}

以及我执行删除操作的位置。

 - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        NSManagedObject *recordtoDelete = [self.arr objectAtIndex:indexPath.row];


        [_managedObjectContext deleteObject:recordtoDelete];

        [self.tableView beginUpdates];

       // Category *deleteRecord = [self.arr objectAtIndex:indexPath.row];
       // [self.managedObjectContext deleteObject:deleteRecord];


        [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath, nil] withRowAnimation:UITableViewRowAnimationFade];

        [self.tableView endUpdates];


        NSError *error = nil;



        if (![_managedObjectContext save:&error]) {

            //handle error here
        }

    }   
    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
    }   
}

好的,所以当我运行这段代码时...

它给出了这种类型的错误...

Terminating app due to uncaught exception `NSInternalInconsistencyException`,reason: 
'Invalid update: invalid number of rows in section 0. 
The number of rows contained in an existing section after the update (17) must be 
equal to the number of rows contained in that section before the update (17), 
plus or minus the number of rows inserted or deleted from that section 
(0 inserted,1 deleted) and plus or minus the number of rows moved into or out of 
that section (0 moved in, 0 moved out).

'

最佳答案

使用 NSFetchResultController 比数组更好,您可以使用 NSFetchResultControllerDelgate 轻松更新 tableView。在 UItableViewController 中你只需要 2 个,如下所示:

@property (strong, nonatomic) NSFetchedResultsController *fetchedResultsController;
@property (strong, nonatomic) NSManagedObjectContext *managedObjectContext;

第一次重写 NSFetchedResultController 的 getter

- (NSFetchedResultsController *)fetchedResultsController

{
if (_fetchedResultsController != nil) {
    return _fetchedResultsController;
}

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Edit the entity name as appropriate.
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Category" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"is_active == 1"];

[fetchRequest setPredicate:predicate];

[fetchRequest setFetchBatchSize:25];


// Edit the sort key as appropriate.
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
NSArray *sortDescriptors = @[sortDescriptor];

[fetchRequest setSortDescriptors:sortDescriptors];

// Edit the section name key path and cache name if appropriate.
// nil for section name key path means "no sections".
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:@"Master"];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;

NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error]) {
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    abort();
}

return _fetchedResultsController;
}    

重写数据源

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return [[self.fetchedResultsController sections] count];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    id <NSFetchedResultsSectionInfo> sectionInfo = [self.fetchedResultsController sections][section];
    return [sectionInfo numberOfObjects];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
    [self configureCell:cell atIndexPath:indexPath];
    return cell;
}

- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
    Category *category = (Category *)[self.fetchedResultsController objectAtIndexPath:indexPath];

    // Configure the cell...
    cell.textLabel.text = [category name];

    cell.detailTextLabel.text = [category descript];

}

删除

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext];
        [context deleteObject:[self.fetchedResultsController objectAtIndexPath:indexPath]];

        NSError *error = nil;
        if (![context save:&error]) {
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
        }
    }   
}


- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{
    [self.tableView beginUpdates];
}

- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
           atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
{
    switch(type) {
        case NSFetchedResultsChangeInsert:
            [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
}

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
       atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
      newIndexPath:(NSIndexPath *)newIndexPath
{
    UITableView *tableView = self.tableView;

    switch(type) {
        case NSFetchedResultsChangeInsert:
            [tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeUpdate:
            [self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
            break;

        case NSFetchedResultsChangeMove:
            [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
            [tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
    [self.tableView endUpdates];
}

关于ios - 删除记录时出错,由于未捕获的异常而终止应用程序 'NSInternalInconsistencyException',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19033707/

相关文章:

objective-c - 如何在 10.6 中的 Interface Builder 中创建 NSImageCell 的 NSMatrix

ios - UIView animate - 旋转并放大,然后旋转并缩小

ios - UITableViewCell 中 UIView 的圆角半径在 iOS9 中不起作用

ios - iOS 上的 mmap 有时返回 0xffffffff

iphone - Object c property dealloc,哪个是正确的?

ios - CLLocationManager 委托(delegate)不工作

iphone - 从 ACAccountStore 在 iOS 中获取 Facebook uid?

iphone - UIWebView 和 CSS 固定位置

ios - 在 iOS 中比较两个频谱图

iOS模拟器屏幕尺寸