Как определить, где NaN передается API CoreGraphics в Mac OS X 10.9

У меня очень большое графическое приложение для 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?

Скриншот этой ошибки на консоли


person Igor    schedule 04.10.2013    source источник
comment
Вам нужно немного расширить трассировку стека. Механизм диспетчеризации событий является функцией верхнего уровня цикла выполнения, а не графического стека.   -  person CodaFi    schedule 04.10.2013
comment
Эти сообщения появляются в консоли сразу после шага nextEventMatchingMask:. Похоже, события ошибок где-то накапливаются и потом показываются вместе. Как расширить графический стек?   -  person Igor    schedule 04.10.2013
comment
В нижней части панели трассировки стека есть ползунок. Сдвиньте его вправо до упора, а затем посмотрите, какая функция появляется в верхней части кривой.   -  person CodaFi    schedule 04.10.2013
comment
В верхней части стека ничего не появляется, кроме моей текущей функции. Другие потоки также не имеют ничего общего с основной графикой. Просто сообщения об ошибках появляются в окне консоли.   -  person Igor    schedule 04.10.2013
comment
Я получаю эту ошибку в окне консоли для кода, работающего в Xcode 7.1.1 и OS X 10.11.1. Что исправить?   -  person Jayprakash Dubey    schedule 23.11.2015
comment
В моем случае установка другого контроллера представления на существующий экземпляр NSPopover вызвала эту ошибку.   -  person YoonHo    schedule 03.02.2016


Ответы (5)


После долгих поисков я обнаружил, что вы можете установить символическую точку останова на «CGPostError» в Xcode, и это даст вам трассировку стека.

person Tom Dalling    schedule 08.11.2013
comment
ЭТО ПОТРЯСАЮЩИЙ СОВЕТ. - person Fattie; 24.07.2017

Я получал эту ошибку, когда по глупости сохранял NSPopover для будущего использования.

Кажется, popover.showRelativeToRect(_:) это все, что вам нужно сделать, и тогда вы можете забыть об этом.

person Chris    schedule 02.03.2016
comment
Привет, Крис, не могли бы вы объяснить, как решить эту проблему в задаче c - person NSLog; 11.03.2016
comment
В моем случае я сохранял ссылку NSPopover в статической переменной для совместного использования несколькими объектами представления. Похоже, что NSPopover не любит повторное использование после того, как оно было показано. Воссоздание всплывающего окна по запросу, хотя и не идеальное, сделало предупреждение. Взлом CGPostError показывает, что ошибка генерируется в NSPopover -showRelativeToRect:preferredEdge: - person Jonathan Mitchell; 08.07.2016

Привычка создавать ленивые UIView с .zero кадром играла против меня, когда я делал это для PDFView.

Этот

var pdfView = PDFView(frame: .zero)

будет генерировать много одинаковых журналов из вопроса. Причина, по которой я использовал .zero, заключается в том, что позже я настроил представление с ограничениями. Это оказалось проблемой. Решение заключалось в использовании произвольного ненулевого кадра при инициализации файла PDFView.

var pdfView = PDFView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
person nsinvocation    schedule 29.05.2020
comment
ОМГ СПАСИБО БОЛЬШОЕ ЗА ТИИИИИИСССС!!!!!!!! ❤️ - person Marcela Ceneviva Auslenter; 21.06.2021

Я нашел проблему. Это деление на ноль в какой-то момент приводит к NSAffineTransform с элементами NaN в матрице. По некоторым причинам компилятор и ОС пропускали эту ситуацию до 10.9.

person Igor    schedule 04.10.2013

поэтому вы должны получить исключение в этот момент, поэтому точка останова исключения должна работать...

вот на что стоит обратить внимание...

возможно, вы перепутали сигнатуру метода... т.е.

-(float)myHeight
{
    return 56.0;
}

запутался в подклассе

-(int)myHeight
{
    return 42;
}

или у вас плохая математика(и), которая испускает NaN...

есть несколько способов обнаружить NaN... c99 представил isnan()
также трюк ieee float (f != f) будет верным для NaN

person Grady Player    schedule 04.10.2013
comment
Это действительно исключение? Насколько я знаю, это не так — ни Objective-C, ни C++. Раньше вы могли установить точку останова на CGError, хотя я помню, что это явно упоминалось в сообщениях об ошибках Quartz (но у меня никогда раньше не было этой конкретной ошибки). (Пользователи AppCode: начиная с версии 2.1 он не поддерживает символические точки останова — для этого вам придется использовать Xcode.) - person Peter Hosey; 05.10.2013
comment
да, я действительно не знаю, является ли это исключением на данный момент, я давно не занимался разработкой iOS ... @PeterHosey в коде приложения вы получаете доступ к необработанной подсказке gdb / lldb? если это так, вы можете установить символическую точку останова... вы могли бы в xcode даже установить ее с условием f!=f (я думаю, но не проверял) - person Grady Player; 05.10.2013
comment
В AppCode есть панель консоли отладчика, но в половине случаев она не работает (подсказка никогда не появляется). Я не знаю, что вы подразумеваете под «состоянием f!=f». - person Peter Hosey; 05.10.2013
comment
@PeterHosey в Xcode вы можете установить условную точку останова, о которой, я уверен, вы знаете ... но условие для некоторого числа с плавающей запятой f, f!=f (само по себе) верно только для NaN - person Grady Player; 05.10.2013
comment
О верно. Однако потенциальный NaN должен быть в пределах области видимости. Если он получает NaN в коде CG или Foundation, это ограничивает возможности его использования. - person Peter Hosey; 05.10.2013
comment
да, и вам придется назначить его переменной... вряд ли будет легко найти... вероятно{'/ - person Grady Player; 05.10.2013