我尝试删除一行时收到此错误

时间:2014-12-08 22:51:09

标签: ios uitableview

当我尝试删除行时,我收到此错误。请谁帮帮我!!!!

  

由于未捕获的异常'NSInternalInconsistencyException'而终止应用程序,原因:'无效更新:第3节中的行数无效。更新后的现有部分中包含的行数(3)必须等于行数在更新(1)之前包含在该部分中,加上或减去从该部分插入或删除的行数(0插入,0删除)和加或减移入或移出该部分的行数(0移入,0搬出去。)

//
//  InboxTableViewController.m
//  Ribbit
//
//  Created by OnMac on 24/11/14.
//  Copyright (c) 2014 OnMac. All rights reserved.
//

#import "InboxTableViewController.h"
#import "ImageViewController.h"

@interface InboxTableViewController ()

@end

@implementation InboxTableViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    self.recipient = [NSMutableArray arrayWithArray:[self.selectedMessage objectForKey:@"recipientIds"]];

    NSLog(@"Delete: %@", self.selectedMessage);

    self.moviePlayer = [[MPMoviePlayerController alloc] init];

    PFUser *currentUser = [PFUser currentUser];

    if (currentUser) {

        NSLog(@"Currrent user: %@", currentUser.username);
    }

    else {

  [self performSegueWithIdentifier:@"showLogin" sender:self];
    }

}


-(void) viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    PFUser *currentUser = [PFUser currentUser];
    if (currentUser) {



    PFQuery *query = [PFQuery queryWithClassName:@"Message"];
    [query whereKey:@"recipiendID" equalTo:[[PFUser currentUser] objectId]];
    [query orderByDescending:@"createdAt"];
    [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
        if (error) {
            NSLog(@"Error: %@ %@", error, [error userInfo]);

        }

        else{

//        We found messages!!!

            self.messages = objects;
            [self.tableView reloadData];
//            NSLog(@"messages: %@", self.messages);
        }
    }];

    }

    else {

        [self performSegueWithIdentifier:@"showLogin" sender:self];


    }

}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - Table view data source

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

    // Return the number of sections.
    return 1;
}

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

    // Return the number of rows in the section.
    return [self.messages count];

}


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

    // Configure the cell...

    PFObject *message = [self.messages objectAtIndex:indexPath.row];
    cell.textLabel.text = [message objectForKey:@"Username"];
//    NSLog(@"ALT: %@", message);
    NSString *fileType = [message objectForKey:@"fileType"];

    if ([fileType isEqualToString:@"image"]) {

    PFFile *im = [message objectForKey:@"file"];
    NSData *resumeData = [im getData];

    cell.imageView.image = [UIImage imageWithData:resumeData];
    }

    else{

        cell.imageView.image = nil;

    }


    return cell;
}





-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

{
    self.selectedMessage = [self.messages objectAtIndex:indexPath.row];



    NSString *fileType = [self.selectedMessage objectForKey:@"fileType"];

    if ([fileType isEqualToString:@"image"]) {

        [self performSegueWithIdentifier:@"showImage" sender:self];




    }

    else{

//        File type is video


        PFFile *videoFile = [self.selectedMessage objectForKey:@"file"];
        NSURL *fileUrl = [NSURL URLWithString:videoFile.url];
        self.moviePlayer.contentURL = fileUrl;
        [self.moviePlayer prepareToPlay];


//        Add it to the view controller so we can see it

        [self.view addSubview:self.moviePlayer.view];
        [self.moviePlayer setFullscreen:YES animated:YES];




    }


}

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

{

       PFObject *message1 = [self.messages objectAtIndex:indexPath.row];
    [message1 deleteInBackground];

    if (editingStyle == UITableViewCellEditingStyleDelete) {




    [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];


    }



   [self.tableView reloadData];



}

- (IBAction)logout:(id)sender {


    [PFUser logOut];

    [self performSegueWithIdentifier:@"showLogin" sender:self];

}


- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {

    if([segue.identifier isEqualToString:@"showLogin"]) {

        [segue.destinationViewController setHidesBottomBarWhenPushed:YES];

    }

    else if ([segue.identifier isEqualToString:@"showImage"]) {

    [segue.destinationViewController setHidesBottomBarWhenPushed:YES];
        ImageViewController *imageViewController = (ImageViewController *)segue.destinationViewController;
        imageViewController.message = self.selectedMessage;

    }
}

@end    

1 个答案:

答案 0 :(得分:2)

首先,请更多地编辑您的代码。你有更多的空白空间而不是实际的代码,并且粘贴那么多的空白空间只会让这个过程更长。

其次,尝试阅读错误消息。当你没有从表中删除时,它表示你正在删除datasource中的一行。我怀疑发生的事情是在commitEditingStyle方法中:

-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
  PFObject *message1 = [self.messages objectAtIndex:indexPath.row];
  [message1 deleteInBackground];
  if (editingStyle == UITableViewCellEditingStyleDelete) {
    [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
  }
  [self.tableView reloadData];
}

看看你在做什么。这里有很多问题。首先,您在100%的时间内删除了一条消息。这意味着您总是在修改数据源。但是看看你的if语句 - 这意味着你并不总是删除一行。现在,您有时会删除消息而不删除表中的行。这将导致崩溃。

第二 - 从听起来的声音来看,这听起来就像你在后台删除了这条消息。这可能是一件非常糟糕的事情。为什么?因为如果你以异步方式等待委托回调,那么这将导致非常糟糕的竞争条件。

您的代码应如下所示:

-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
  if (editingStyle == UITableViewCellEditingStyleDelete) {
    PFObject *message1 = [self.messages objectAtIndex:indexPath.row];
    [self.messages removeObject:message1];
    [message1 deleteInBackground];

    [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
  }
}

请注意,我添加了[self.messages removeObject:message1]以使您的dataSource立即与表保持一致。我不知道你在[PFObject deleteInBackground]做了什么,但如果你没有立即从dataSource删除邮件对象,那么你可能会遇到不好的问题。