UITableView崩溃显示“CALayerInvalidGeometry”,原因是“CALayer position contains NaN:[160 nan]”

20
我在我的应用程序中有一个自定义的表格视图。我已经实现了“加载更多”的功能,每次加载25行。问题是,在加载两次后,应用程序会崩溃,并在4.2及以上版本的操作系统上给出“CALayerInvalidGeometry”错误,原因是“CALayer position contains NaN: [160 nan]”。
在4.2以下的操作系统上,一个单元格消失了,表格中间有空白。它不会导致任何崩溃。但是它仍然会产生上述错误。
我检查了我的代码看哪里可能会发生0除以的情况,但是我找不到任何问题。按照堆栈跟踪,我发现这个异常发生的位置无法确定。
有人有任何想法吗?
    0   CoreFoundation                      0x020ccbe9 __exceptionPreprocess + 185
 1   libobjc.A.dylib                     0x022215c2 objc_exception_throw + 47
 2   CoreFoundation                      0x02085628 +[NSException raise:format:arguments:] + 136
 3   CoreFoundation                      0x0208559a +[NSException raise:format:] + 58
 4   QuartzCore                          0x0182396a _ZL18CALayerSetPositionP7CALayerRKN2CA4Vec2IdEEb + 177
 5   QuartzCore                          0x018238b5 -[CALayer setPosition:] + 42
 6   QuartzCore                          0x018237cc -[CALayer setFrame:] + 763
 7   UIKit                               0x0073c307 -[UIView(Geometry) setFrame:] + 255
 8   UIKit                               0x008c718a -[UITableViewCell setFrame:] + 166
 9   UIKit                               0x0077aa08 -[UITableView(UITableViewInternal) _createPreparedCellForGlobalRow:withIndexPath:] + 1160
 10  UIKit                               0x0077077f -[UITableView(UITableViewInternal) _createPreparedCellForGlobalRow:] + 75
 11  UIKit                               0x00785450 -[UITableView(_UITableViewPrivate) _updateVisibleCellsNow:] + 1561
 12  UIKit                               0x0077d538 -[UITableView layoutSubviews] + 242
 13  QuartzCore                          0x01828451 -[CALayer layoutSublayers] + 181
 14  QuartzCore                          0x0182817c CALayerLayoutIfNeeded + 220
 15  QuartzCore                          0x0182137c _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 310
 16  QuartzCore                          0x018210d0 _ZN2CA11Transaction6commitEv + 292
 17  QuartzCore                          0x018517d5 _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 99
 18  CoreFoundation                      0x020adfbb __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 27
 19  CoreFoundation                      0x020430e7 __CFRunLoopDoObservers + 295
 20  CoreFoundation                      0x0200bbd7 __CFRunLoopRun + 1575
 21  CoreFoundation                      0x0200b240 CFRunLoopRunSpecific + 208
 22  CoreFoundation                      0x0200b161 CFRunLoopRunInMode + 97
 23  GraphicsServices                    0x02611268 GSEventRunModal + 217
 24  GraphicsServices                    0x0261132d GSEventRun + 115
 25  UIKit                               0x0071542e UIApplicationMain + 1160

奇怪的是,这个错误只发生在表格的第43行。其余所有行都正常显示。 - Tarang
这个问题让我失眠了好久,有人有什么好的想法吗? - marchinram
我们需要查看代码才能帮助您。 - viggio24
请提供loadMore代码。我在我的应用程序中做到了这一点,没有任何问题。 - VdesmedT
5个回答

28
我遇到了完全相同的错误,因为我没有正确地编写

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { ... }
我写道:
- (NSInteger)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { ... }

(请注意返回的值)

希望这能帮助到某些人。

2
我浪费了整个一天的时间.. 现在终于解决了问题.. 感谢 @Moszi - Rupesh
谢谢!这个也救了我!要是我早点看到就好了! - Paul Cooper
谢谢!不知怎么搞的,我把它写成了布尔类型! - John Gibb
有趣。为什么至少有24个人在回调方法的返回值上使用了错误的类型? - Nikolai Ruhe

21

堆栈跟踪显示UITableView在布局可见单元格时发生了异常。由于单元格的位置似乎被设置为NaN值,因此必须询问如何发生这种情况。

假设UITableView布局代码中没有错误,那么唯一可能发生这种情况的方式是:您在表视图委托中实现了tableView:heightForRowAtIndexPath:方法并返回了不良高度(或相应的标头或页脚方法之一)。

编辑:为了确定异常的确切原因:

我假设您从字符串的几何大小(使用UIStringDrawing-[NSString sizeWithFont:]方法)计算单元格的高度。当您向空值发送消息时,返回值通常为nil、0、NO或表示所有位为零的字的任何值。

对于返回结构体的方法(例如sizeWithFont:),情况并非如此。返回的结构体根本没有初始化,其元素包含随机值。

在您的情况下,您可能使用了CGSize结构体的未初始化元素,后来发现它们不是有效的IEEE 754浮点值。

附加说明:自clang 3.0以来,从消息返回的结构体已初始化为{0}(所有位都为零)。因此,上述问题不应再发生。


我确实实现了tableView:heightForRowAtIndexPath:方法来返回自定义的行高,但是我不确定它如何返回错误的高度?你能详细说明一下吗? - marchinram
你说得对,这与tableView:heightForRowAtIndexPath:方法有关,我将其注释掉后,现在可以正常工作而且不会崩溃。但是对于我的应用程序,我需要能够动态更改行高以适应内容。你有什么建议,如何做到这一点并返回一个良好的值,以避免崩溃? - marchinram
这个问题是在设备上还是模拟器上出现的,还是两者都有?你使用了其他几何覆盖(例如 tableView:heightForHeaderInSection:tableView:heightForFooterInSection:)吗?你能发布一下项目吗? - Nikolai Ruhe
不,我没有使用任何这些方法。我可以发送给您我的应用程序的一部分示例代码。但由于用户隐私问题,我无法发送正在运行的代码。您可以查看代码。这是代码链接:http://dl.dropbox.com/u/13284881/Sample_Code.zip 我还看到您编辑了帖子,将字体大小作为原因之一。我也注释掉了设置字体大小的位置,但仍然相同。 - Tarang
在配置 UISlider 时,我也遇到了同样的问题 // 当我将 playlistSlider.frame = CGRectMake(20, 920,width , 60); 注释掉后,问题停止了。 - Lior Frenkel
显示剩余2条评论

5

2

简单回答:

从任何与高度相关的委托方法返回 NaN 会导致此错误。

 tableView:heightForRowAtIndexPath:
 tableView:heightForHeaderInSection:
 tableView:heightForFooterInSection:

可能会有其他导致此错误的方法,但如果您正在使用UITableView,请首先检查此问题!


0
对我来说,这是由于代码中的toView为nil引起的:
    [UIView transitionFromView:self.fromView
                        toView:self.toView
                      duration:0.6
                       options:(currentPage > toPage ? UIViewAnimationOptionTransitionCurlDown : UIViewAnimationOptionTransitionCurlUp)
                    completion:^(BOOL finished) {
                        if (finished) {
                        }
                    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接