如何检测 NaN 在哪里传递给 Mac OS X 10.9 上的 CoreGraphics API

Posted

技术标签:

【中文标题】如何检测 NaN 在哪里传递给 Mac OS X 10.9 上的 CoreGraphics API【英文标题】:How to detect where NaN is passing to CoreGraphics API on Mac OS X 10.9 【发布时间】:2013-10-04 17:29:26 【问题描述】:

我有非常大的图形 Mac 应用程序,现在我在 10.9 GM 的控制台中收到很多以下消息。

<Error>: Error: this application, or a library it uses, has passed an invalid numeric value (NaN, or not-a-number) to CoreGraphics API. This is a serious error and contributes to an overall degradation of system stability and reliability. This notice is a courtesy: please fix this problem. It will become a fatal error in an upcoming update.

我注意到这些消息在调用 [NSApp nextEventMatchingMask: untilDate inMode: dequeue] 后出现在调试器中,但我认为原因在其他一些地方。但是我有太多地方使用 Cocoa Graphics。我在 10.9 之前没有收到这种消息。

如何检测 NaN 传递给 CoreGraphics API 的位置?

【问题讨论】:

您需要进一步扩展堆栈跟踪。事件分派机制是运行循环的顶层函数,而不是图形堆栈。 这些消息在跳过 nextEventMatchingMask: 后立即出现在控制台中。似乎,错误事件在某处累积,然后一起显示。如何扩展图形堆栈? 堆栈跟踪窗格底部有一个滑块。将其尽可能向右滑动,然后查看轨迹顶部出现的函数。 除了我当前的函数外,没有任何东西出现在堆栈的顶部。其他线程也没有与核心图形相关的东西。控制台窗口中只会出现错误消息。 就我而言,将另一个视图控制器设置为现有的 NSPopover 实例会导致此错误。 【参考方案1】:

经过大量挖掘,我发现您可以在 Xcode 中的“CGPostError”上设置一个符号断点,这将为您提供堆栈跟踪。

【讨论】:

这是一个令人兴奋的提示。【参考方案2】:

当我愚蠢地保留一个 NSPopover 以供将来使用时,我遇到了这个错误。

看来popover.showRelativeToRect(_:) 是你需要做的所有事情,然后你就可以忘记它了。

【讨论】:

嗨,克里斯,你能解释一下如何在目标 c 中解决这个问题 在我的例子中,我将一个 NSPopover 引用存储在一个静态变量中,以便在多个视图对象之间共享。看起来 NSPopover 不喜欢在显示后被重复使用。按需重新创建弹出框虽然并不理想,但确实引起了警告。打破 CGPostError 表明错误是在 NSPopover -showRelativeToRect:preferredEdge: 中生成的【参考方案3】:

在为PDFView 做这件事时,用.zero 框架创建懒惰UIView 的习惯对我不利。

这个

var pdfView = PDFView(frame: .zero)

将从问题中生成许多相同的日志。我之所以使用.zero,是因为后来我设置了带有约束的视图。这被证明是一个问题。解决方案是在初始化PDFView 时使用任意非零帧。

var pdfView = PDFView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))

【讨论】:

天啊,非常感谢 THIIIIISSSS!!!!!!! ❤️【参考方案4】:

我发现了问题。它在某个点被零除,导致 NSAffineTransform 与矩阵中的 NaN 元素。由于某些原因,编译器和操作系统在 10.9 之前通过了这种情况。

【讨论】:

【参考方案5】:

所以你应该在那个时候得到一个异常,所以一个异常断点应该可以工作......

这里有一些事情要注意...

您可能弄乱了方法签名...即

-(float)myHeight

    return 56.0;

在子类中搞砸了

-(int)myHeight

    return 42;

或者你有一些糟糕的数学运算会发出一个 NaN...

有几种方法可以检测 NaN... c99介绍isnan()(f != f) 的 ieee 浮点技巧也适用于 NaN

【讨论】:

这真的是个例外吗? AFAIK,它不是——Objective-C 和 C++ 都不是。你曾经可以在CGError 上设置断点,虽然我记得在 Quartz 的错误消息中明确提到过(但我以前从未遇到过这个特定的错误)。 (AppCode 的用户:从 2.1 开始,它不支持符号断点——您必须为此使用 Xcode。) 是的,我现在真的不知道这是否是一个例外,我已经很长时间没有进行 ios 开发了... @PeterHosey in appcode 你可以访问原始 gdb /lldb 提示?如果是这样,您可以设置一个符号断点...您甚至可以在 xcode 中设置一个条件为 f!=f 的断点(我想,但尚未测试) 在 AppCode 中,有一个调试器控制台面板,但有一半时间它不起作用(提示永远不会出现)。我不知道您所说的“f!=f 的条件”是什么意思。 @PeterHosey 在 Xcode 中你可以设置一个条件断点,我相信你已经知道了......但是对于一些 float f, f!=f (本身)的条件仅适用于 NaN 哦,对了。不过,潜在的 NaN 需要在范围内。如果它在 CG 或 Foundation 代码中得到 NaN,则限制了您可以使用它的位置。

以上是关于如何检测 NaN 在哪里传递给 Mac OS X 10.9 上的 CoreGraphics API的主要内容,如果未能解决你的问题,请参考以下文章

Mac OS X 上的 GCC 标志 -Os 来自哪里?

如何在 Mac OS X 中检测是不是连接了蓝牙音频设备?

如何在 shell 脚本中确定 Mac OS X 版本?

我在哪里可以获得 Mac OS X 旧的 SDK?

Mac OS X 上的 Qt 库和源代码安装在哪里?

在 mac os x 上安装 MEAN 时出错