iOS 6/7 中的“未重用表格单元格的索引路径”消息是什么意思?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12772197/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 20:38:08  来源:igfitidea点击:

What is the meaning of the "no index path for table cell being reused" message in iOS 6/7?

iosios6uitableviewios7

提问by Nathan Brown

Since starting to compile my app with iOS 6 (and since also iOS 7) I've started seeing this message. I know that the way that UITableViews go about managing cells is different in iOS 6 but I haven't needed to modify my code for it to keep working. But I'm concerned this message may point to some potential issue that I'm not yet seeing. Can anyone shed any light?

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

回答by mluisbrown

I started to get this error showing up in the log from iOS 7 beta 5 onwards, including in the iOS 7 GM/Release build, whilst never having had it happen in my app in iOS 6 or the earlier iOS 7 betas. After a lot of experimenting I found the cause:

从 iOS 7 beta 5 开始,我开始在日志中显示此错误,包括在 iOS 7 GM/Release 版本中,而在 iOS 6 或更早的 iOS 7 beta 中的应用程序中从未发生过。经过大量试验,我找到了原因:

I was using UITableViewCellobjects for my section header views and returning them in tableView:viewForHeaderInSection:. This appears to be common practice, especially since iOS 5 when it became easy to design a section header view as a prototype table view cell in a StoryBoard with Interface Builder.

我正在UITableViewCell为我的部分标题视图使用对象并将它们返回到tableView:viewForHeaderInSection:. 这似乎是一种常见的做法,尤其是在 iOS 5 之后,当使用 Interface Builder 在 StoryBoard 中将部分标题视图设计为原型表视图单元格变得很容易。

When I changed my app to use just regular UIViewsubclasses for my section header views, the errors went away and, more importantly, my table view stopped randomly deleting section headers!

当我将我的应用程序更改为仅使用UIView节标题视图的常规子类时,错误消失了,更重要的是,我的表格视图停止了随机删除节标题!

It would appear that (since iOS 7 beta 5) UITableViewis internally maintaining a mapping of all the UITableViewCellobjects in its view hierarchy and their respective index paths. Since a section header (or a table view header of footer) doesn't have an index path, if you use a UITableViewCellobject for these views, the table view will get confused when it finds a UITableViewCellfor which it doesn't have an index path, resulting in the "no index path for table cell being reused" error and, if you're unlucky, display glitches in your table view:

看起来(从 iOS 7 beta 5 开始)UITableView在内部维护UITableViewCell其视图层次结构中所有对象及其各自索引路径的映射。由于节头(或页脚的表视图头)没有索引的路径,如果您使用UITableViewCell的这些视图对象,表视图会感到困惑,当它找到一个UITableViewCell为它不具有索引路径,导致“没有重用表格单元格的索引路径”错误,如果你不走运,会在你的表格视图中显示故障:

UPDATE: if you have access to the Apple Dev Forums, here's the thread about it (which I started): https://devforums.apple.com/message/882042#882042

更新:如果您可以访问 Apple Dev Forums,这里是关于它的主题(我开始的):https: //devforums.apple.com/message/882042#882042

As suggested in that thread, if you don't want to re-factor much, you can create a UIViewwrapper around your UITableViewCelland return that as the section header view.

正如该线程中所建议的那样,如果您不想进行太多重构,则可以UIView在您的周围创建一个包装器UITableViewCell并将其作为部分标题视图返回。

UIView *view = [[UIView alloc] initWithFrame:[cell frame]];
[view addSubview:cell];

return view;

Note however that this "wrapper" UIViewapproach will not play well with AutoLayout and device rotation, so I suggest that you use a UIViewsubclass for header and footer cells, not a UITableViewCellsubclass as explained in the main part of the answer.

但是请注意,这种“包装器”UIView方法不适用于 AutoLayout 和设备旋转,因此我建议您UIView为页眉和页脚单元使用子类,而不是UITableViewCell答案主要部分中解释的子类。

回答by mar-schmidt

I'd return the contentView of the UITableViewCell instead of creating a wrapper.. having constraint-jabble fixed in storybord in mind

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

return cell.contentView;

回答by mpprdev

I had the same problem and it took me few hours to hunt down the issue. Turns out I was calling [textField becomeFirstResponder]while setting up cells (here the textField was part of a custom tableviewcell); [textField becomeFirstResponder]in turns posts keyboardWillShow notification which in turn caused the tableview to prematurely load itself thus causing the infamous "no index path for table cell being reused” message. Once I removed that call, problem disappeared.

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

回答by Rob

Addition to the accepted answer (mluisbrown), I needed to add an autoresizingMask to the header cell, since mine contained a multi-line label, i.e.

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

UIView *view = [[UIView alloc] initWithFrame:[cell frame]];
cell.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
[view addSubview:cell];
return view;

回答by diegoreymendez

This is an internal UIKit bug - as mentioned in Apple's own dev forums. It's supposedly fixed in newer versions of xcode, although I wasn't able to find info regarding which version fixes this.

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

回答by diegoreymendez

As an addition to my previous post (in which I mentioned that this was apparently a bug with UIKit), I was able to find a workaround for my particular case (in which the message was related to some strange visualisation glitches on the table).

作为我上一篇文章的补充(其中我提到这显然是 UIKit 的一个错误),我能够找到针对我的特定情况的解决方法(其中消息与桌子上的一些奇怪的可视化故障有关)。

Apparently my custom cell's overridden -(void)setEditing:animated:was taking too long to return.

显然,我的自定义单元格被覆盖-(void)setEditing:animated:需要很长时间才能返回。

My previous code was:

我之前的代码是:

- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{   
    [super setEditing:editing animated:animated];
    [self someAdditionalCode];
}

I was able to fix it by changing it to:

我能够通过将其更改为:

- (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];
    });
}

回答by Dan

I had the same problem with the error message appearing. As far as I can see it is caused by reloading the table view from a function called by the the textfield as part of its delegate protocol. Ie textFieldDidEndEditing -> [controller.tableview reload...]

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

回答by Daniel ?kesson

Doing my endupdates after resignfirstresponder solved my problem (Have a UITextFIeld in my custom cell)

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

-(void)textfieldEditDone
{
....

    [textField resignFirstResponder];
    [self.tableView endUpdates];

回答by siburb

This is obviously an old question, but hopefully this can help anyone who still gets this issue in iOS8+ because this is still the top question that comes up for this particular error message.

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

I was using PINRemoteImage to async download an image to a UIImageView that was inside a custom UITableViewCell.

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

In order to resize the row properly (dynamic height cells using auto-layout) once the image had loaded, I called:

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

self.tableView beginUpdates;
self.tableView endUpdates;

I was then getting the "no index path for table cell being reused" message and the app was crashing. I had thought the PINRemoteImageManagerResult block was on the main thread, however it turns out that it wasn't - therefore ensuring that the begin/end updates was called on the main thread fixed the issue.

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

dispatch_async(dispatch_get_main_queue(), ^(void){
                            [self.tableView beginUpdates];
                            [self.tableView endUpdates];
});

回答by Fred The Bishop

For the record, I encountered this message too when running under iOS 6. It appears that some code either inherited or imported had something like this:

作为记录,我在 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];
    }
}

When the beginUpdate: / endUpdate: sequence was removed, the problem magically disappeared.

当 beginUpdate: / endUpdate: 序列被删除后,问题就神奇地消失了。