Приложение зависает, но загрузка ЦП со временем увеличивается

Я застрял на этой вещи в течение многих часов, и я не знаю, что еще искать.

Я мало что могу предоставить, поскольку отладчик не показывает никаких ошибок, но это воспроизводимо — я нажимаю на очень конкретный элемент в табличном представлении, действие которого должно отклонить это модальное окно, а затем мое приложение зависает. Этого не происходит с другими элементами в табличном представлении — модальное окно полностью закрывается, и приложение продолжает работу.

Однако я проверил этот ответ, подозревая, что это тупик:

  • Каждый раз, когда я нажимаю кнопку паузы в отладчике, основной поток занят чем-то другим.
  • Использование ЦП, как видно из навигатора отладки Xcode, со временем увеличивается.
  • Я ставлю точки останова в один из моих пользовательских методов UIControl layoutSubviews, и он продолжает вызываться. Он не вызывает [super layoutSubviews], не вызывает setNeedsLayout ни у кого, а просто устанавливает кадры своих подпредставлений, потому что я не использую Autolayout.

Как я могу отладить эту вещь? Я просматривал инструменты Xcode, но не могу понять данные, которые вижу. В частности, шаблон System Trace, по-видимому, способен останавливаться сразу после зависания, в отличие от других, которые продолжают запись.

Добавлено: что я вижу в трассировке системы что я вижу в трассировке системы


person MLQ    schedule 14.04.2015    source источник
comment
Вы проверили вызов рекурсивного метода после нажатия на эту ячейку. Добавьте немного кода   -  person Sumanth    schedule 14.04.2015
comment
Можете ли вы подтвердить, что не манипулируете пользовательским интерфейсом из фонового потока? didSelectRowAtIndexPath не вызывается в основном потоке при любых обстоятельствах (stackoverflow.com/a/22173707/80678)   -  person kenleycapps    schedule 14.04.2015
comment
@kenleycapps Нет, didSelectRowAtIndexPath не работает в фоновом потоке. Он работает в основном потоке, там нет dispatch_asyncs.   -  person MLQ    schedule 14.04.2015
comment
Инструмент профилирования времени, вероятно, будет более полезным. Выберите инвертировать дерево вызовов и скрыть системные библиотеки и посмотреть, что он показывает   -  person Paulw11    schedule 14.04.2015


Ответы (2)


Инструменты — это инструмент, с помощью которого вы хотите диагностировать проблему. Попробуйте проверить свое приложение с помощью Time Profiler, выполнив задачу, которую вы наблюдали, чтобы увеличить загрузку ЦП, а затем проанализировать результаты, проверив Invert Call Tree и Hide System Libraries. Вы также можете установить временные маркеры, если есть определенный период времени, который вы хотите проверить. Отсюда видно, какие вызовы загружают ЦП.

person nmock    schedule 14.04.2015

Комментарий @Paulw11 помог — шаблон Time Profiler лучше подходит для этой задачи, чем инструмент System Trace.

Я использовал Time Profiler и получил кучу трассировок, которые указывают на UINavigationBar как на подозрительного повторяющегося вызывающего абонента для моего пользовательского UIControl layoutSubviews. Для дальнейшего объяснения моей иерархии представлений:

  • Мой контроллер представления "Home" имеет собственное представление заголовка в своем UINavigationItem.
  • Пользовательский вид заголовка — это настраиваемый UIControl, который запускает модальное окно при касании.

Вот в чем дело: если я alloc-initWithFrame использую свой собственный UIControl с рамкой CGRectZero, приложение зависает. Если я передам фрейму ненужное начальное значение (которое в любом случае игнорируется, поскольку UINavigationBar изменяет форму моего пользовательского UIControl), например CGRectMake(0, 0, 10, 10), сбой не происходит.

Я предполагаю, что UINavigationBar запутался в том, как разместить собственное представление заголовка с начальным кадром (0, 0, 0, 0). Похоже на баг Apple.

Примечание. Я использую iOS 8.2.

person MLQ    schedule 14.04.2015