Причина UITableView: "CALayerInvalidGeometry", причина: "Позиция CALayer содержит NaN: [160 nan] '
У меня есть собственное представление таблицы в моем приложении. Я выполнил функцию "Загрузить больше" в таблицу, которая загружает 25 строк за раз. Проблема заключается в загрузке в 2 раза сбоя приложения, что дает "CALayerInvalidGeometry", причина: "Позиция CALayer содержит NaN: [160 nan]" как ошибку на OS 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
Ответы
Ответ 1
У меня была такая же точная ошибка, потому что вместо записи
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { ... }
Я написал:
- (NSInteger)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { ... }
(обратите внимание на возвращаемое значение).
Надеюсь, это поможет кому-то.
Ответ 2
Трассировка стека выглядит так: UITableView занят компоновкой видимых ячеек при возникновении исключения. Поскольку положение ячейки, как представляется, имеет значение NaN
, нужно спросить, как это может произойти.
Предполагая, что в коде макета UITableView нет ошибки, единственный способ, которым это может произойти, заключается в том, что вы реализуете tableView:heightForRowAtIndexPath:
в своем делегате представления таблиц и возвращаете плохую высоту (или один из соответствующих методов заголовка или нижнего колонтитула).
Изменить, чтобы точно определить причину исключения:
Я предполагаю, что вы рассчитали высоту ячейки из геометрического размера строки (используя UIStringDrawing
-[NSString sizeWithFont:]
). Когда вы отправляете сообщение в значение nil, возвращаемое значение обычно равно nil, 0, NO или любое другое значение представлено словом с полным битом.
Для метода, который возвращает struct (as sizeWithFont:
), это неверно. Возвращенная структура не инициализируется вообще, содержащая случайные значения для ее элементов.
В вашем случае вы, вероятно, использовали один из неинициализированных элементов структуры CGSize, который позже оказался недействительным значением с плавающей запятой IEEE 754.
Добавление: Так как clang 3.0 структуры, возвращаемые из сообщений, инициализируются на {0} (все биты ноль). Поэтому выше проблемы больше не должно быть.
Ответ 3
Сообщения, которые возвращают структуры structs, могут возвращать значения undefined во внутренней структуре.
В практическом плане это означает, что получение frame
из nil
UIView
может возвращать значения undefined в поле size
frame
. Эта ошибка просто укусила меня, и я был удивлен.
Ответ 4
Простой ответ:
Возврат NaN из любого метода делегирования, связанного с высотой, вызывает эту ошибку.
tableView:heightForRowAtIndexPath:
tableView:heightForHeaderInSection:
tableView:heightForFooterInSection:
и т.д..
Могут быть другие способы произвести эту ошибку, но если вы работаете с UITableView - сначала проверьте это!
Ответ 5
Для меня это было вызвано тем, что toView в этом коде равен нулю:
[UIView transitionFromView:self.fromView
toView:self.toView
duration:0.6
options:(currentPage > toPage ? UIViewAnimationOptionTransitionCurlDown : UIViewAnimationOptionTransitionCurlUp)
completion:^(BOOL finished) {
if (finished) {
}
}