58

自从开始使用 iOS 6(以及 iOS 7)编译我的应用程序以来,我已经开始看到此消息。我知道 UITableViews 管理单元格的方式在 iOS 6 中有所不同,但我不需要修改我的代码以使其继续工作。但我担心此消息可能会指出一些我尚未看到的潜在问题。任何人都可以解释一下吗?

4

14 回答 14

132

从 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答案主要部分中解释的子类。

于 2013-09-12T16:10:16.507 回答
41

我会返回 UITableViewCell 的 contentView 而不是创建包装器.. 在 storybord 中固定约束-jabble

return cell.contentView;
于 2014-12-10T17:12:54.320 回答
26

我遇到了同样的问题,我花了几个小时来解决这个问题。原来我是[textField becomeFirstResponder]在设置单元格时调用的(这里的 textField 是自定义 tableviewcell 的一部分);[textField becomeFirstResponder]依次发布keyboardWillShow通知,这反过来导致tableview过早地加载自身,从而导致臭名昭著的“没有重复使用表格单元的索引路径”消息。一旦我删除了那个调用,问题就消失了。

于 2013-12-31T02:45:22.140 回答
16

除了接受的答案(mluisbrown)之外,我还需要在标题单元格中添加一个 autoresizingMask,因为我的包含一个多行标签,即

UIView *view = [[UIView alloc] initWithFrame:[cell frame]];
cell.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
[view addSubview:cell];
return view;
于 2014-03-31T01:47:16.660 回答
8

这是一个内部 UIKit 错误 - 正如 Apple 自己的开发论坛中提到的那样。据说它已在较新版本的 xcode 中修复,尽管我无法找到有关哪个版本修复此问题的信息。

于 2012-10-07T21:39:32.873 回答
4

作为对我之前文章的补充(其中我提到这显然是 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];
    });
}
于 2012-10-07T23:32:04.783 回答
2

出现错误消息时我遇到了同样的问题。据我所知,这是由于从文本字段调用的函数重新加载表视图引起的,作为其委托协议的一部分。即 textFieldDidEndEditing -> [controller.tableview 重新加载...]

于 2013-11-01T18:44:31.907 回答
2

在 resignfirstresponder 解决我的问题后做我的 endupdates(在我的自定义单元格中有一个 UITextFIeld)

-(void)textfieldEditDone
{
....

    [textField resignFirstResponder];
    [self.tableView endUpdates];
于 2014-04-19T08:25:25.780 回答
1

作为记录,我在 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: 序列被删除后,问题就神奇地消失了。

于 2013-04-15T19:32:21.343 回答
1

这显然是一个老问题,但希望这可以帮助在 iOS8+ 中仍然遇到此问题的任何人,因为这仍然是针对此特定错误消息提出的首要问题。

我正在使用 PINRemoteImage 将图像异步下载到自定义 UITableViewCell 内的 UIImageView。

为了在图像加载后正确调整行的大小(使用自动布局的动态高度单元格),我调用了:

self.tableView beginUpdates;
self.tableView endUpdates;

然后我收到“没有重复使用表格单元的索引路径”消息,应用程序崩溃了。我原以为 PINRemoteImageManagerResult 块在主线程上,但事实证明它不是 - 因此确保在主线程上调用开始/结束更新解决了这个问题。

dispatch_async(dispatch_get_main_queue(), ^(void){
                            [self.tableView beginUpdates];
                            [self.tableView endUpdates];
});
于 2015-09-02T00:04:07.983 回答
0

好吧,我只是利用一天中的大部分时间试图弄清楚这一点,所以希望这种替代解释可以为其他人节省一些时间。

我有一个 tableview有时会在加载时给出这个消息。事实证明,这是由在加载视图时触发 Core Data 对象的 KVO 通知引起的。(在观察到变化时,我的控制器尝试在有问题的 tableview 上调用 reloadData。通过在视图完成加载之前不观察对象来修复(以前,一旦通过访问器分配对象,我就开始观察对象)

TLDR:检查您是否正在尝试从主线程以外的其他地方重新加载数据。

于 2014-04-09T11:16:52.493 回答
0

也许这对某人有帮助:我曾经在刷新单个表格视图单元格时遇到此错误。我的意思是做类似的事情

NSIndexPath *reloadRow = [NSIndexPath indexPathForRow:1 inSection:2];
[self._mainTableView reloadRowsAtIndexPaths:@[reloadWebViewRow]
                           withRowAnimation:UITableViewRowAnimationFade];

但不小心,我输入了

NSIndexPath *reloadRow = [NSIndexPath indexPathForItem:1 inSection:2];

注意两个索引路径的区别:一个是用indexPathForItem(错误)创建的,另一个是用indexPathForRow(正确)创建的。这一切都导致了 tableView 的非常奇怪的行为和标题中的错误消息。

于 2014-04-17T07:13:04.323 回答
0

似乎我的问题是在我尝试在作为网络调用回调的部分代码中更新 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];
});
于 2015-01-16T04:52:31.563 回答
0

还有一个条件...

这发生在我不想要标题时,我返回了nil.

使固定:

func tableView(tableView: UITableView,
               titleForHeaderInSection section: Int) -> String? {
    return ""
}
于 2015-10-20T15:04:33.690 回答