是啥导致了这个错误? “CALayer 位置包含 NaN:[240 nan]”
Posted
技术标签:
【中文标题】是啥导致了这个错误? “CALayer 位置包含 NaN:[240 nan]”【英文标题】:What causes this error? "CALayer position contains NaN: [240 nan]"是什么导致了这个错误? “CALayer 位置包含 NaN:[240 nan]” 【发布时间】:2011-03-02 19:06:45 【问题描述】:每当我旋转带有UITableView
的屏幕时,我都会看到这种情况发生。我发现它发生在UIViewController
中的willRotate
和didRotate
方法调用之间,我的同事在其他地方也看到了它,通常是围绕旋转。它直到最近才开始发生,我们不知道应该如何处理它(谷歌搜索不会以确切的形式出现错误消息)。有没有其他人遇到过这种情况知道该怎么做?
【问题讨论】:
【参考方案1】:(决定将其从 cmets 中取出并将其作为答案,因为我认为这是一个非常好的答案:)
哈!我也有一个 NaN 计算(div0)。关键调试辅助:有问题的消息是由 NSLog() 输出的,所以在 NSLog() 上设置一个断点并观察操作系统当时正在做什么。对我来说,它是 myUISlider.value = NaN。
设置断点:
XCode 3.x
CMD-SHIFT-Y(调试窗口。) 断点按钮。 “双击符号” 输入“NSLog”(不加引号。)XCode 4.x
CMD-6(断点导航器。) “+”添加断点(左下角) 选择添加符号断点。 符号:NSLog 确认:完成。XCode 5.x - 7.1(至少) (与 4.x 相同,除了断点导航器现在是 CMD-7。)
运行应用程序,观察它在 NSLog 上的中断,检查堆栈跟踪。
【讨论】:
这是关于这个异常的真正重要的答案。请务必注意,使用 CALayer 的组件可能会引发此异常,而我们 API 用户不知道它们的存在(感谢封装)。 很好,调试方法+1。 @Caio:如果你没有得到断点,(a)验证你的断点在 NSLog() 上中断(做一个测试日志),(b)你得到的错误可能是不是由 NSLog() 输出的;看看你能不能在别处休息。我的答案的关键是:因为我找不到要破解的代码,所以我破解了输出消息的位。也许在你的堆栈跟踪中查找一些 ios 异常处理代码并尝试打破它。 @Olie 终于知道到底发生了什么。除以零是由内部 UIScrollView 方法进行的,所以这就是断点在 NSLog 上没有中断的原因。有时一个约束可以是 0。 在 Xcode 8 中,我有一个CALayer position contains NaN
以 NSException
结尾。设置异常断点:所有异常都给了我堆栈跟踪。 (符号断点:NSLog
没有。)【参考方案2】:
我找到了问题。
当您重置tableview
的框架时,它会为表中的每一行调用委托方法tableView:heightForRowAtIndexPath:
,以便它可以在需要时重新计算其内容大小。那时,我们做了一些特殊的处理来返回高度,并且由于我们的代码中的一些错误假设,我们错误地返回了NaN
,因为除以零错误(我们除以的变量被假定永远不会为零) .确保我们不会在此处除以零。
【讨论】:
我遇到了同样的错误(位置和边界都包含 NaN,消息通常成对出现。)仅在我的视图显示之前。没有旋转,没有表格,没有花哨的计算。一个简单的深灰色视图,带有标签“处理中...”和进度指示器。还有其他人对此有想法吗? 在您的 viewdidload/viewwillappear 方法中放置一些断点,并确保您不会在任何地方意外除以零。 它可能相关也可能不相关,但我在 Mavericks OSX 10.9 中更一致地看到了这种崩溃,但在 OSX 10.9.2 更新后没有再次出现。 这让我更好地了解了我的项目中的问题...由于我使用单独的情节提要,我呈现的 viewController 有一个我没有发送正确值的 tableView到。【参考方案3】:我花了一天时间试图找到导致相同问题的代码,并在 Xcode 中启用“异常中断”后一分钟内解决了它。检查this tutorial 以了解如何启用它。
【讨论】:
您能否附上页面内容的简短摘要?这样,这篇文章的未来读者可以快速轻松地获得他们正在寻找的信息。 @gobernador 我会的,因为它帮助了我!要找到您的应用程序死掉的确切行,请转到 xcode 左侧的断点选项卡,单击 +,添加新的Exception Breakpoint
并将设置保留为默认值。点击完成并重新运行您的应用。【参考方案4】:
当我假设我遇到了这个问题:
tableView:heightForHeaderInSection:
返回了 NSInteger
,但它返回了 CGFloat
...
改变:
-(NSInteger)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
到
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
解决了我的问题。
编辑:
在某个时候,我弄清楚了计算机在 C 级别以下是如何工作的,所以我想我会分享它...(我将使用 x86_64 中的寄存器名称,因为我最熟悉它们,ARM 会略有不同,但类似的)
int f()
float someFloat=5.0f;
return someFloat;
导致将someFloat
的值转换为整数类型,然后将其复制到特定寄存器:%rax
然后调用返回指令。
float f()
float someFloat=5.0f;
return someFloat;
导致将someFloat
的值从其当前位置复制到特定寄存器:%xmm0
,然后调用返回指令。
所以如果你有错误的原型,调用代码会认为值在错误的位置,你最终会返回一个垃圾值。
【讨论】:
【参考方案5】:这个错误也让我花了很长时间。 最后我发现我的同事写了这样一段话:
UIEdgeInsets a;
a.left = (...some calculation);
button.imageEdgeInsets = a;
我像这样重写了这些代码并解决了这个问题:
UIEdgeInsets a;
a.left = (...some calculation);
a.top = 0;
a.bottom = 0;
a.right = 0;
button.imageEdgeInsets = a;
UIEdgeInsets 的某些值未正确初始化,有时会变成 NaN 值,导致应用程序崩溃。 更一般地说,您应该检查 C 风格结构的所有值是否都已正确初始化。
【讨论】:
【参考方案6】:还有另一种重现问题的方法:在太小的矩形上使用insetBy(dx:dy:)
【讨论】:
【参考方案7】:你可以试试这个yourTableview?.bounces = false
。它对我有用。
【讨论】:
以上是关于是啥导致了这个错误? “CALayer 位置包含 NaN:[240 nan]”的主要内容,如果未能解决你的问题,请参考以下文章
调试 'CALayer 位置包含 NaN: [nan nan]'
随机“CALayerInvalidGeometry 原因:CALayer 位置包含 NaN”异常