从表视图中删除数据会使应用程序崩溃

Posted

技术标签:

【中文标题】从表视图中删除数据会使应用程序崩溃【英文标题】:Deleting data from table view crashes the app 【发布时间】:2016-08-10 06:24:12 【问题描述】:

在这里,当我单击删除按钮时,应用程序崩溃并给出错误:尝试从对象 [0] 插入 nil 对象' 这是我的代码。

@implementation ViewDetailViewController

- (NSManagedObjectContext *)managedObjectContext

    NSManagedObjectContext *context = nil;
    id delegate = [[UIApplication sharedApplication] delegate];
    if ([delegate performSelector:@selector(managedObjectContext)]) 
        context = [delegate managedObjectContext];
    
    return context;


- (void)viewDidLoad 
    [super viewDidLoad];


    // Fetch the devices from persistent data store
    NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Personal"];
    self.devices = [[managedObjectContext executeFetchRequest:fetchRequest error:nil] mutableCopy];

    self.searchResult = [NSMutableArray arrayWithArray:self.devices];

    [self.tableView reloadData];


    // Do any additional setup after loading the view, typically from a nib.



- (void)viewDidAppear:(BOOL)animated

    [super viewDidAppear:animated];

    // Fetch the devices from persistent data store
    NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Personal"];
    self.devices = [[managedObjectContext executeFetchRequest:fetchRequest error:nil] mutableCopy];

    self.searchResult = [NSMutableArray arrayWithArray:self.devices];

    [self.tableView reloadData];


    // Do any additional setup after loading the view.

这是我的表格视图委托方法。

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView

    // Return the number of sections.
    return 1;


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

    return [self.searchResult count];


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    // Configure the cell...
    NSManagedObject *device = [self.searchResult objectAtIndex:indexPath.row];

    
        [cell.textLabel setText:[NSString stringWithFormat:@"%@", [device valueForKey:@"name"]]];
        [cell.detailTextLabel setText:[device valueForKey:@"attribute"]];
    
    return cell;

删除数据的代码。

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

    NSManagedObjectContext *context = [self managedObjectContext];

    if (editingStyle == UITableViewCellEditingStyleDelete) 
        // Delete object from database
        [context deleteObject:[self.devices objectAtIndex:indexPath.row]];

        NSError *error = nil;
        if (![context save:&error]) 
            NSLog(@"Can't Delete! %@ %@", error, [error localizedDescription]);
            return;
        
        static NSString *CellIdentifier = @"Cell";
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
        NSIndexPath *cellIndexPath = [self.tableView indexPathForCell:cell];

        //Remove device from table view
        [self.devices removeObjectAtIndex:indexPath.row];
        [tableView deleteRowsAtIndexPaths:@[cellIndexPath] withRowAnimation:UITableViewRowAnimationFade];
    

【问题讨论】:

你的代码哪里出错了? 当我点击删除按钮时,应用程序崩溃......当我重建应用程序时,该行被删除。意味着它正在被删除,但当我点击删除 @Carter 时应用程序崩溃 当应用崩溃时,你知道是哪一行代码导致它崩溃吗? 从不cellForRowAtIndexPath 之外创建重复使用的单元格,而且根本不需要。索引路径传入commitEditingStyle 【参考方案1】:

在您的数据源方法中,您使用 self.searchResult

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

    return [self.searchResult count];

但在commitEditingStyle: 中,您会从[self.devices removeObjectAtIndex:indexPath.row]; 中删除数据

你需要改变这个

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    
        return [self.devices count];
    

或改变

[self.searchResult removeObjectAtIndex:indexPath.row];

还有一件事你不需要得到cellIndexPath这个参数传递给方法

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

  NSManagedObjectContext *context = [self managedObjectContext];

 if (editingStyle == UITableViewCellEditingStyleDelete) 
            // Delete object from database
            [context deleteObject:[self.devices objectAtIndex:indexPath.row]];

            NSError *error = nil;
            if (![context save:&error]) 
                NSLog(@"Can't Delete! %@ %@", error, [error localizedDescription]);
                return;
            

        //Remove device from table view
        [self.devices removeObjectAtIndex:indexPath.row];
        //[self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];

    

【讨论】:

我已经尝试了你建议的两种方式,但它不起作用仍然在单击删除时崩溃。 我的答案有点改变 没有帮助...查看设备我看到设备是我的主要数组,searchResult 是我用于搜索栏数据的数组【参考方案2】:

请这个代码可以使用完整

[self.searchResult removeObjectAtIndex:indexPath.row];
[tableview reload];

【讨论】:

没有帮助...查看设备我看到设备是我的主要数组,searchResult 是我用于搜索栏数据的数组【参考方案3】:

尝试删除此行:[tableView deleteRowsAtIndexPaths:@[cellIndexPath] withRowAnimation:UITableViewRowAnimationFade]; 看来您不应该删除 commitEditingStyle 中的单元格。该委托会自动执行此操作。

【讨论】:

这是错误的,除非你使用 NSFetchedResultsController 及其委托方法。

以上是关于从表视图中删除数据会使应用程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章

搜索后重新加载视图会使应用程序崩溃

从表视图中删除一行

添加视图数组会使 android 应用程序崩溃

从表视图中删除特定行

UITableView 行删除崩溃应用

即使在删除之后,Core Data 命令也会使 ViewController 崩溃