如何检测 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的主要内容,如果未能解决你的问题,请参考以下文章