为什么reloadRowsAtIndexPaths不能用于iOS 5.0?

已解决:请参阅下面的答案(以及可能的解释)。

我正在制作适用于iOS 5.1设备的应用程序,但不适用于iOS 5.0设备。 以下是适用于5.1但不适用于5.0的故障代码:

- (void) expandIndexPath: (NSIndexPath *) indexPath afterDelay: (BOOL) delay { NSIndexPath *oldSelectedIndexPath = [NSIndexPath indexPathForRow:self.mySelectedIndex inSection:0]; self.mySelectedIndex= indexPath.row; // [self.myTableView beginUpdates]; [self.myTableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:[NSIndexPath indexPathForRow:self.mySelectedIndex inSection:0], oldSelectedIndexPath,nil] withRowAnimation:UITableViewRowAnimationNone]; // [self.myTableView endUpdates]; } 

更奇怪的是,如果我用[self.myTableView reloadData];替换reloadRowsAtIndexPaths行,它可以在iOS 5.0中运行[self.myTableView reloadData]; 。 为什么是这样? 5.0有关于reloadRowsAtIndexPaths行的错误吗? 我已经尝试在5.0上使用和不使用begin/endUpdates行并且都begin/endUpdates

编辑:更具体地说,当我在iOS 5上运行应用程序时,崩溃时出现以下错误:

*断言失败-[_UITableViewUpdateSupport _computeRowUpdates] ,/ /SourceCache/UIKit/UIKit-1912.3/UITableViewSupport.m:386 -[_UITableViewUpdateSupport _computeRowUpdates] /SourceCache/UIKit/UIKit-1912.3/UITableViewSupport.m:386 [切换到进程7171线程0x1c03]

由于未捕获的exception’ NSInternalInconsistencyException ‘而终止应用程序,原因:’无效的表视图更新。 应用程序已请求更新表视图,该更新与数据源提供的状态不一致。

编辑:这是我的UITableViewDataSource方法。

 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { //I am positive that this will ALWAYS return the number (it never changes) return self.myCellControllers.count; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { //I cache my table view cells, thus each time this method gets called it will // return the exact same cell. Yes, I know that most of the time I should be dequeing // and reusing cells; just trust me that this time, it's best for me to cache them // (There are very few cells so it doesn't really matter) CellController *controller = [self.myCellControllers objectAtIndex:indexPath.row]; return controller.myCell; } - numberOfSectionsInTableView: always returns 1; 

唯一有趣的方法是

 - (CGFloat)tableView:(UITableView *)aTableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { if(indexPath.row == self.mySelectedIndex) { return DEFAULT_CELL_HEIGHT + self.expandSize; } else { return DEFAULT_CELL_HEIGHT; } } 

正如快速概述程序的这一部分如何工作一样,当用户点击一个单元格时,单元格会滚动到屏幕顶部。 在它位于屏幕顶部之后,它的索引被设置为self.mySelectedIndex并且它会扩展(变得更高)。

我找到了一个有效的解决方案。 如果我将expandIndexPath方法更改为this它可以工作:

 - (void) expandIndexPath: (NSIndexPath *) indexPath afterDelay: (BOOL) delay { [self.myTableView beginUpdates]; NSIndexPath *oldSelectedIndexPath = [NSIndexPath indexPathForRow:self.mySelectedIndex inSection:0]; self.mySelectedIndex= indexPath.row; if(oldSelectedIndexPath.row >= 0) { [self.myTableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:[NSIndexPath indexPathForRow:self.mySelectedIndex inSection:0],oldSelectedIndexPath, nil] withRowAnimation:UITableViewRowAnimationNone]; } else { [self.myTableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:[NSIndexPath indexPathForRow:self.mySelectedIndex inSection:0],nil] withRowAnimation:UITableViewRowAnimationNone]; } [self.myTableView endUpdates]; } 

据我所知,问题是oldSelectedIndexPath有时被设置为负行值。 因此,当我尝试重新加载带有负行的indexPath时,它在iOS 5.0中崩溃了。 似乎iOS 5.1修复此问题并进行更多错误检查。