自从开始使用 iOS 6(以及 iOS 7)编译我的应用程序以来,我已经开始看到此消息。我知道 UITableViews 管理单元格的方式在 iOS 6 中有所不同,但我不需要修改我的代码以使其继续工作。但我担心此消息可能会指出一些我尚未看到的潜在问题。任何人都可以解释一下吗?
14 回答
从 iOS 7 beta 5 开始,我开始在日志中出现这个错误,包括在 iOS 7 GM/Release 版本中,而在我的 iOS 6 或更早的 iOS 7 beta 中的应用程序中从未发生过。经过大量的实验,我找到了原因:
我正在为我的部分标题视图使用UITableViewCell
对象并将它们返回到tableView:viewForHeaderInSection:
. 这似乎是一种常见的做法,尤其是自 iOS 5 以来,当使用 Interface Builder 将节标题视图设计为 StoryBoard 中的原型表视图单元格变得很容易时。
当我将应用程序更改为仅对UIView
节标题视图使用常规子类时,错误消失了,更重要的是,我的表格视图停止随机删除节标题!
看起来(自 iOS 7 beta 5 起)UITableView
在内部维护UITableViewCell
其视图层次结构中所有对象及其各自索引路径的映射。由于节标题(或页脚的表视图标题)没有索引路径,如果您为这些视图使用对象,则表视图在找到没有索引路径UITableViewCell
的 a 时会感到困惑UITableViewCell
,导致“没有重复使用表格单元格的索引路径”错误,如果你不走运,在表格视图中显示故障:
更新:如果您可以访问 Apple 开发论坛,这里是关于它的主题(我开始的):https ://devforums.apple.com/message/882042#882042
正如该线程中所建议的,如果您不想重构太多,您可以UIView
在您的周围创建一个包装器UITableViewCell
并将其作为节标题视图返回。
UIView *view = [[UIView alloc] initWithFrame:[cell frame]];
[view addSubview:cell];
return view;
但是请注意,这种“包装器”UIView
方法不适用于 AutoLayout 和设备旋转,因此我建议您使用UIView
页眉和页脚单元格的子类,而不是UITableViewCell
答案主要部分中解释的子类。
我会返回 UITableViewCell 的 contentView 而不是创建包装器.. 在 storybord 中固定约束-jabble
return cell.contentView;
我遇到了同样的问题,我花了几个小时来解决这个问题。原来我是[textField becomeFirstResponder]
在设置单元格时调用的(这里的 textField 是自定义 tableviewcell 的一部分);[textField becomeFirstResponder]
依次发布keyboardWillShow通知,这反过来导致tableview过早地加载自身,从而导致臭名昭著的“没有重复使用表格单元的索引路径”消息。一旦我删除了那个调用,问题就消失了。
除了接受的答案(mluisbrown)之外,我还需要在标题单元格中添加一个 autoresizingMask,因为我的包含一个多行标签,即
UIView *view = [[UIView alloc] initWithFrame:[cell frame]];
cell.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
[view addSubview:cell];
return view;
这是一个内部 UIKit 错误 - 正如 Apple 自己的开发论坛中提到的那样。据说它已在较新版本的 xcode 中修复,尽管我无法找到有关哪个版本修复此问题的信息。
作为对我之前文章的补充(其中我提到这显然是 UIKit 的一个错误),我能够找到针对我的特定情况的解决方法(其中消息与桌子上的一些奇怪的可视化故障有关)。
显然,我的自定义单元格被覆盖-(void)setEditing:animated:
需要很长时间才能返回。
我之前的代码是:
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
[super setEditing:editing animated:animated];
[self someAdditionalCode];
}
我能够通过将其更改为来修复它:
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
[super setEditing:editing animated:animated];
// DRM: we want to perform the actions from this block in the main thread, but
// asynchronously to avoid excessive delays which were causing issues.
//
dispatch_async(dispatch_get_main_queue(), ^void()
{
[self someAdditionalCode];
});
}
出现错误消息时我遇到了同样的问题。据我所知,这是由于从文本字段调用的函数重新加载表视图引起的,作为其委托协议的一部分。即 textFieldDidEndEditing -> [controller.tableview 重新加载...]
在 resignfirstresponder 解决我的问题后做我的 endupdates(在我的自定义单元格中有一个 UITextFIeld)
-(void)textfieldEditDone
{
....
[textField resignFirstResponder];
[self.tableView endUpdates];
作为记录,我在 iOS 6 下运行时也遇到了此消息。似乎继承或导入的某些代码具有以下内容:
(NSInteger)tableView:(UITableView *)tv numberOfRowsInSection:(NSInteger)section {
NSInteger rows = 0;
if ([delegate respondsToSelector:@selector(numberOfItemsInSection:)]) {
rows = [delegate numberOfItemsInSection:section];
[tableView beginUpdates];
[tableView endUpdates];
}
}
当 beginUpdate:/endUpdate: 序列被删除后,问题就神奇地消失了。
这显然是一个老问题,但希望这可以帮助在 iOS8+ 中仍然遇到此问题的任何人,因为这仍然是针对此特定错误消息提出的首要问题。
我正在使用 PINRemoteImage 将图像异步下载到自定义 UITableViewCell 内的 UIImageView。
为了在图像加载后正确调整行的大小(使用自动布局的动态高度单元格),我调用了:
self.tableView beginUpdates;
self.tableView endUpdates;
然后我收到“没有重复使用表格单元的索引路径”消息,应用程序崩溃了。我原以为 PINRemoteImageManagerResult 块在主线程上,但事实证明它不是 - 因此确保在主线程上调用开始/结束更新解决了这个问题。
dispatch_async(dispatch_get_main_queue(), ^(void){
[self.tableView beginUpdates];
[self.tableView endUpdates];
});
好吧,我只是利用一天中的大部分时间试图弄清楚这一点,所以希望这种替代解释可以为其他人节省一些时间。
我有一个 tableview有时会在加载时给出这个消息。事实证明,这是由在加载视图时触发 Core Data 对象的 KVO 通知引起的。(在观察到变化时,我的控制器尝试在有问题的 tableview 上调用 reloadData。通过在视图完成加载之前不观察对象来修复(以前,一旦通过访问器分配对象,我就开始观察对象)
TLDR:检查您是否正在尝试从主线程以外的其他地方重新加载数据。
也许这对某人有帮助:我曾经在刷新单个表格视图单元格时遇到此错误。我的意思是做类似的事情
NSIndexPath *reloadRow = [NSIndexPath indexPathForRow:1 inSection:2];
[self._mainTableView reloadRowsAtIndexPaths:@[reloadWebViewRow]
withRowAnimation:UITableViewRowAnimationFade];
但不小心,我输入了
NSIndexPath *reloadRow = [NSIndexPath indexPathForItem:1 inSection:2];
注意两个索引路径的区别:一个是用indexPathForItem
(错误)创建的,另一个是用indexPathForRow
(正确)创建的。这一切都导致了 tableView 的非常奇怪的行为和标题中的错误消息。
似乎我的问题是在我尝试在作为网络调用回调的部分代码中更新 UI 时触发的。我通过强制 UI 更新在主线程上进行解决。我使用了这样的代码。
void runOnMainQueueWithoutDeadlocking(void (^block)(void)){
if ([NSThread isMainThread])
{
block();
}
else
{
dispatch_sync(dispatch_get_main_queue(), block);
}
}
我在后台网络调用的成功块内按如下方式调用它。
runOnMainQueueWithoutDeadlocking(^{
[self.tableView beginUpdates];
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:1] withRowAnimation:UITableViewRowAnimationAutomatic];
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:2] withRowAnimation:UITableViewRowAnimationAutomatic];
[self.tableView endUpdates];
});
还有一个条件...
这发生在我不想要标题时,我返回了nil
.
使固定:
func tableView(tableView: UITableView,
titleForHeaderInSection section: Int) -> String? {
return ""
}