从 uitableview cellForRowAtIndexPath 委托中删除行时应用程序崩溃
app crash while deleting row from within uitableview cellForRowAtIndexPath delegate
我有一个 table view.i 正在实现一个功能,其中单元格将开始褪色(随着 30 秒的持续时间减少 alpha)。完成 30 秒后,视图动画的完成处理程序是调用以从数据源(数组)中永久删除行。所有的东西都在 cellForRowAtIndexPath 委托方法中。
我的问题是在更新前和更新后保持数组计数同步。
代码:
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *postCellId = @"postCell";
UITableViewCell *cell = nil;
NSUInteger row = [indexPath row];
cell = [tableView dequeueReusableCellWithIdentifier:postCellId];
if (cell == nil) {
cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:postCellId] autorelease];
}
Post *currentPost = [posts objectAtIndex:row];
cell.textLabel.text = [currentPost postTitle];
cell.textLabel.font = [UIFont systemFontOfSize:14];
cell.detailTextLabel.text = [currentPost postDescr];
cell.detailTextLabel.font = [UIFont systemFontOfSize:10];
NSTimeInterval duration = 30;
[UIView animateWithDuration:duration delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionAllowUserInteraction
animations:^ {
cell.contentView.alpha = 0;
} completion:^(BOOL finished) {
[self.tableView beginUpdates];
NSLog(@"delete index >> %d from array >> %@", row, posts);
[posts removeObjectAtIndex:indexPath.row];
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates];
}];
return cell;
}
日志:
2015-06-04 07:22:05.764 Feeder[1177:60b] delete index >> 0 from array
(
"",
"",
"",
"",
"" ) 2015-06-04 07:22:05.766 Feeder[1177:60b] delete index >> 1 from array >> (
"",
"",
"",
"" ) 2015-06-04 07:22:05.767 Feeder[1177:60b] delete index >> 2 from array >> (
"",
"",
"" ) 2015-06-04 07:22:05.768 Feeder[1177:60b] delete index >> 3 from array >> (
"",
"" )
如果看到最后一条log,就是crash的问题。
崩溃日志:
2015-06-04 07:22:05.770 Feeder[1177:60b] * Terminating app due to
uncaught exception 'NSRangeException', reason: '* -[__NSArrayM
removeObjectAtIndex:]: index 3 beyond bounds [0 .. 1]'
如何解决。
你的错误是你在块中保留了旧的 indexPath,而不是更新它。
例如:
如果数组中有 2 条记录,则完整块中的操作是
- 删除第 0 行
- 删除第 1 行
但是,如果您删除第一个单元格(第 0 行),您的第 1 行 indexPath.row 会更新为 0.But 您要删除的第 1 行。
所以,我认为你可以动态获取indexPath,然后删除
[self.tableView beginUpdates];
NSIndexPath *path = [tableView indexPathForCell:cell];
NSLog(@"delete index >> %d from array >> %@", path.row, posts);
[posts removeObjectAtIndex:path.row];
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:path] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates];
我不确定这是否有效,请尝试。
你可以试试这个:
[self.tableView beginUpdates];
NSInteger postIndex = [posts indexOfObject:currentPost];
NSIndexPath *path = [NSIndexPath indexPathForRow:postIndex inSection:0];
NSLog(@"delete index >> %d from array >> %@", path.row, posts);
[posts removeObject:currentPost];
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:path] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates];
我有一个 table view.i 正在实现一个功能,其中单元格将开始褪色(随着 30 秒的持续时间减少 alpha)。完成 30 秒后,视图动画的完成处理程序是调用以从数据源(数组)中永久删除行。所有的东西都在 cellForRowAtIndexPath 委托方法中。 我的问题是在更新前和更新后保持数组计数同步。
代码:
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *postCellId = @"postCell";
UITableViewCell *cell = nil;
NSUInteger row = [indexPath row];
cell = [tableView dequeueReusableCellWithIdentifier:postCellId];
if (cell == nil) {
cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:postCellId] autorelease];
}
Post *currentPost = [posts objectAtIndex:row];
cell.textLabel.text = [currentPost postTitle];
cell.textLabel.font = [UIFont systemFontOfSize:14];
cell.detailTextLabel.text = [currentPost postDescr];
cell.detailTextLabel.font = [UIFont systemFontOfSize:10];
NSTimeInterval duration = 30;
[UIView animateWithDuration:duration delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionAllowUserInteraction
animations:^ {
cell.contentView.alpha = 0;
} completion:^(BOOL finished) {
[self.tableView beginUpdates];
NSLog(@"delete index >> %d from array >> %@", row, posts);
[posts removeObjectAtIndex:indexPath.row];
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates];
}];
return cell;
}
日志:
2015-06-04 07:22:05.764 Feeder[1177:60b] delete index >> 0 from array
( "", "", "", "", "" ) 2015-06-04 07:22:05.766 Feeder[1177:60b] delete index >> 1 from array >> ( "", "", "", "" ) 2015-06-04 07:22:05.767 Feeder[1177:60b] delete index >> 2 from array >> ( "", "", "" ) 2015-06-04 07:22:05.768 Feeder[1177:60b] delete index >> 3 from array >> ( "", "" )
如果看到最后一条log,就是crash的问题。
崩溃日志:
2015-06-04 07:22:05.770 Feeder[1177:60b] * Terminating app due to uncaught exception 'NSRangeException', reason: '* -[__NSArrayM removeObjectAtIndex:]: index 3 beyond bounds [0 .. 1]'
如何解决。
你的错误是你在块中保留了旧的 indexPath,而不是更新它。
例如: 如果数组中有 2 条记录,则完整块中的操作是
- 删除第 0 行
- 删除第 1 行
但是,如果您删除第一个单元格(第 0 行),您的第 1 行 indexPath.row 会更新为 0.But 您要删除的第 1 行。
所以,我认为你可以动态获取indexPath,然后删除
[self.tableView beginUpdates];
NSIndexPath *path = [tableView indexPathForCell:cell];
NSLog(@"delete index >> %d from array >> %@", path.row, posts);
[posts removeObjectAtIndex:path.row];
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:path] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates];
我不确定这是否有效,请尝试。
你可以试试这个:
[self.tableView beginUpdates];
NSInteger postIndex = [posts indexOfObject:currentPost];
NSIndexPath *path = [NSIndexPath indexPathForRow:postIndex inSection:0];
NSLog(@"delete index >> %d from array >> %@", path.row, posts);
[posts removeObject:currentPost];
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:path] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates];