2013-07-05 3 views
3

В моем приложении для iPhone я иногда вижу сбой, вызванный tableView: cellForRowAtIndexPath: вызывается в фоновом потоке.Почему tableView: cellForRowAtIndexPath: вызывается в фоновом потоке?

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

 
-_WebTryThreadLock(bool) 
-_dequeuReusableViewOfType 
-tableView:cellForRowAtIndexPath: 
-_createPreparedCellForGlobalRow:withIndexPath 
-_pthread_qathread 

Катастрофа происходит в WebTryThreadLock - нет Удивительно, что это не потокобезопасно и не следует отвлекать от основной темы.

Но как выяснить, почему мой делегат tableView вызывается в фоновом потоке?

Мне интересно - если бы я должен был вызвать [tableView reloadData] в фоновом потоке, сделал бы это?

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

+0

Можете ли вы разместить подробный журнал аварий. Кроме того, вы включаете какие-либо сторонние структуры (вообще)? –

+1

Вы спрашиваете: «Не должен ли UIKit проверять это?» Я могу понять, почему вы спрашиваете об этом, но простой факт заключается в том, что это не так, и вы просто должны просто обеспечить, чтобы ваши связанные с табличным вызовом вызовы выполнялись в основной очереди. – Rob

+0

опубликуйте свой код и журнал сбоев, чтобы получить лучший ответ – Jatin

ответ

3

Вы не можете позвонить по номеру [tableView reloadData] по второстепенной теме. Вы не можете называть любой материал UIKit на вторичном потоке (за некоторыми исключениями, например UIImage). Это включает в себя все методы tableView, включая прямые геттеры и сеттеры. Не имеет значения, относится ли это отношение или нет.

+0

Это было мое понимание, спасибо за подтверждение этого. После тщательной проверки моего кода, я уверен, что я НЕ делаю этого. Но я сделаю тройной чек, чтобы быть уверенным втрое. Итак, можете ли вы придумать какой-либо (другой) сценарий, который может привести к созданию фундамента, вызывающего cellForRowAtIndexPath: в потоке bg? – Jordan

+2

@Jordan Существуют четыре разных метода 'reload ...' для табличных представлений, поэтому убедитесь, что вы не вызываете их из фонового потока. Также методы 'scrollTo ...'. Также не назовите ничего, что изменило бы рамку вашего представления таблицы или, например, вытащил бы контроллер просмотра, который вы на него набросили, и т. Д. Это все вещи UIKit, поэтому, если вы убедитесь, что вы делаете все вызовы UIKit из главной очереди, все будет хорошо. – Rob

+1

«так что если вы убедитесь, что все вызовы UIKit из главной очереди, вы будете в порядке» - да, ну, это то, о чем я думал. Похоже, что у меня есть какой-то код, который делает это, но я еще не нашел его! – Jordan

2

Это может быть интересно посыпать некоторые из них вокруг вашего контроллера вида: (! [NSThread isMainThread])

если { NSLog (@ "? Да"); }

Я уверен, что UIKit/IOS не решит самостоятельно вызвать метод делегата табличного представления в фоновом потоке. У вас есть dispatch_async, detachNewThreadSelector, выполняетSelectorInBackground?

+0

> Я уверен, что UIKit/IOS не решит, что он сам будет вызывать метод делегата таблицы> в фоновом потоке. Да, это тоже было мое убеждение, и до сих пор у меня нет причин верить иначе. – Jordan

+0

Я проверяю isMainThread везде, где могу, и делаю сброс стека в местах, где я нахожу, что я нахожусь в неправильном потоке, в надежде узнать, как я туда попал. – Jordan

+0

+1 для .... Да? –

 Смежные вопросы

  • Нет связанных вопросов^_^