Сбой UITableView дает 'CALayerInvalidGeometry', причина: 'Положение CALayer содержит NaN: [160 нан.]' - PullRequest
20 голосов
/ 27 января 2011

У меня есть собственное представление таблицы в моем приложении. Я реализовал функцию «Загрузить еще» для таблицы, которая загружает 25 строк одновременно. Проблема заключается в том, что после двухкратной загрузки приложения происходит сбой, выдавая «CALayerInvalidGeometry», причина: «Положение CALayer содержит NaN: [160 nan]» в качестве ошибки на ОС 4.2 и выше.

В ОС ниже 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

Ответы [ 5 ]

28 голосов
/ 17 марта 2011

У меня была точно такая же ошибка, потому что вместо записи

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { ... }

я написал:

- (NSInteger)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { ... }

(обратите внимание на возвращаемое значение). Надеюсь, это кому-нибудь поможет.

21 голосов
/ 08 февраля 2011

Трассировка стека выглядит так, как будто UITableView занят созданием видимых ячеек при возникновении исключения.Поскольку положение ячейки, по-видимому, установлено в значение NaN, нужно спросить, как это может произойти.

Если предположить, что в коде макета UITableView нет ошибки, единственный способ это сделать - этовнедрите tableView:heightForRowAtIndexPath: в свой делегат табличного представления и верните неверную высоту (или один из соответствующих методов верхнего или нижнего колонтитула).

Отредактируйте , чтобы точно указать причину исключения:

Я предполагаю, что вы вычислили высоту ячейки по геометрическому размеру строки (используя UIStringDrawing 's -[NSString sizeWithFont:]).Когда вы отправляете сообщение со значением nil, возвращаемое значение обычно равно nil, 0, NO или какому-либо значению, представленному словом все биты с нулем.

Для метода, который возвращает структуру (какsizeWithFont:) это не так.Возвращенная структура вообще не инициализируется и содержит случайные значения для ее элементов.

В вашем случае вы, вероятно, использовали один из неинициализированных элементов структуры CGSize, который позже оказался не действительным IEEE 754значение с плавающей запятой.

Приложение: Начиная с clang 3.0, структуры, возвращаемые из сообщений, инициализируются в {0} (все биты равны нулю).Так что вышеупомянутой проблемы больше не должно быть.

5 голосов
/ 08 сентября 2011

Сообщения в ноль, которые возвращают структуры структур, могут возвращать неопределенные значения во внутренней структуре.

На практике это означает, что получение frame из nil UIView может возвращать неопределенные значения в поле size frame. Эта ошибка просто укусила меня, и я был удивлен.

2 голосов
/ 16 апреля 2011

Простой ответ:

Возврат NaN из любого метода, связанного с высотой, вызывает эту ошибку.

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

и т. Д.

Могут быть другие способы вызвать эту ошибку, но если вы работаете с UITableView - сначала проверьте это!

0 голосов
/ 05 мая 2013

Для меня это было вызвано тем, что toView в этом коде равно nil:

    [UIView transitionFromView:self.fromView
                        toView:self.toView
                      duration:0.6
                       options:(currentPage > toPage ? UIViewAnimationOptionTransitionCurlDown : UIViewAnimationOptionTransitionCurlUp)
                    completion:^(BOOL finished) {
                        if (finished) {
                        }
                    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...