Итак, вот моя проблема.
На домашней странице моего приложения у меня есть простой UITableView, который может содержать максимум 3 раздела, 2 раздела максимум по 3 элемента в каждом, а третий раздел может содержать максимум 6 элементов.
Каждый раздел имеет заголовок, связанный с.
Фактический контент поступает из Интернета, я делаю запрос, сервер отправляет данные, я анализирую ответ с помощью NSXMLParser, создаю массивы для хранения данных для каждого раздела (3 массива), а также создаю другой массив для хранения ссылки на разделы мне придется отображать.
Затем, в конце, я вызываю [myTableView reloadData], чтобы обновить содержимое и перерисовать таблицу.
Пользователи также имеют возможность самостоятельно обновлять контент. Для этого я использую механизм Pull-to-Refresh, как и приложение Facebook.
Обновление контента с использованием pull-to-refresh также заканчивается вызовом [myTableView reloadData].
Я испытываю неприятный сбой, когда обновляю содержимое, и таблица должна изменить свое расположение (например, таблица в настоящее время содержит все 3 раздела, а после перезагрузки данных будет отображаться только один раздел).
Я использовал отладчик, чтобы отследить проблему. Вот что я нашел:
- Пользователь сносит всю таблицу примерно на 50 пикселей, а затем отпускает
- Начинается анимация, которая поднимает таблицу вверх, чтобы вместить представление 320x50 с отображением сообщения «Загрузка» + UIActivityIndicatorView, анимированного в верхней части таблицы
- Обновление запущено, я делаю новый запрос веб-сервиса в фоновой задаче, получаю новые данные, анализирую, обновляю массивы и, наконец, в основном потоке выполняю reloadData
- Тем временем, пока обновление выполняет все, что я заметил, UITableView STILL отправляет сообщения делегата:
- Tableview: viewForHeaderInSection:
- Tableview: cellForRowAtIndexPath:
Я полагаю, что это происходит из-за анимации pull-to-refresh, которая «перемещает» таблицу вверх и выявляет новые ячейки / заголовки, вызывая, таким образом, выше.
Проблема в том, что это вызывает ужасный сбой, потому что массивы, которые содержат данные для разделов, и сам массив разделов изменяются одновременно.
Когда это происходит, методы делегата, вероятно, используют обновленный / еще не обновленный массив элементов / разделов в неправильном контексте. То есть до
- numberOfSectionsInTableView:
- tableView: numberOfRowsInSection:
когда-либо получит шанс правильно обновить новую структуру для обновленных массивов.
Я знаю, что это длинная история без какого-либо примера кода, но я подумал, что, если я уже знаю проблему (по крайней мере, я надеюсь, что знаю), и если кто-то видит мою точку зрения, возможно, что кто-то может указать мне правильное направление, чтобы исправить это проблема синхронизации.
Спасибо за чтение!
ПОСЛЕДНЕЕ РЕДАКТИРОВАНИЕ :
Я нашел, где была проблема. Мой механизм pull-to-refresh использует обратный вызов stopLoading, который выглядит следующим образом:
- (void)stopLoading
{
isLoading = NO;
// Hide the header
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDelegate:self];
[UIView setAnimationDuration:0.3];
[UIView setAnimationDidStopSelector:@selector(stopLoadingComplete:finished:context:)];
self.myTableView.contentInset = UIEdgeInsetsZero;
[refreshArrow layer].transform = CATransform3DMakeRotation(M_PI * 2, 0, 0, 1);
[UIView commitAnimations];
}
В какой-то момент я сбросил contentInset для моей таблицы, установив его в UIEdgeInsetsZero.
Это и тот факт, что после фонового обновления, возвращающегося в основном потоке, я вызывал stopLoading ПЕРЕД reloadData - вызвал неправильные обратные вызовы делегата в неправильный момент.
Так что это была проблема синхронизации между изменением contentInset моей таблицы и reloadData.