当我尝试删除行时,我收到此错误。请谁帮帮我!!!!
由于未捕获的异常'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
答案 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
删除邮件对象,那么你可能会遇到不好的问题。