2015-01-22 4 views
0

У меня проблема с потоками в приложении iOS. Это большое приложение, которое развивается в течение нескольких лет. (Я нахожусь в числе многих участников этого проекта и имею только глубокое понимание некоторых его частей).Проблема Threading в heightForRowAtIndexPath

В некоторых случаях приложение подвергается фоновому обновлению, которое вызывает методы делегата tableview. Иногда это вызывает следующее исключение:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Only run on the main thread!' 

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

Итак, я могу проверить, не нахожусь ли я на основном потоке, находясь внутри heightForRowAtIndexPath.

Если я не в основном потоке, я могу вызвать performSelectorOnMainThread в попытке получить высоту ячейки, единственной проблемой является то, что heightForRowAtIndexPath возвращается до того, как селектор вернется, поэтому высота ячейки будет равна нулю. Итак, это ситуация с курицей до яйца. Как заставить вызов основного потока в heightForRowAtIndexPath и быть уверенным, что он не вернется, прежде чем выполнить командуSelectorOnMainThread? Или это даже возможно? Благодаря!

+1

Вы пытаетесь исправить ошибку. Не исправить 'heightForAtIndexPath', исправить код, который пытается перезагрузить или обновить таблицу из фонового потока. – rmaddy

ответ

3

Проблема не с heightForRowAtIndexPath, это только кажется, вы перегрузочные TableView в фоновом потоке. Попробуйте сделать это

 
[self.tableview performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO]; 
+0

'reloadData' - это метод' UITableView'. 'self', вероятно, является контроллером представления, а не табличным представлением. – rmaddy

+0

Спасибо за исправление @rmaddy –

4

Вы можете получить фон Threading с помощью GCD, для этого вам не нужно вручную управлять данными. GCD выполнит все для вас.

Вот кусок кода

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 

    //// DO some Background Processing Like Data Fetching 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     // Do some UIUpdates in your case call TableView Datasource 
     [yourtable reloaddata]; 
    }); 
}); 
Смежные вопросы