Threadsafe UITableView - PullRequest
       10

Threadsafe UITableView

4 голосов
/ 02 декабря 2008

Я использую UITableView, чтобы показать некоторые данные из массива. Этот массив может быть изменен в любое время другими потоками. (Я считаю, что независимо от того, является ли массив изменчивым или просто полностью заменен, не имеет значения.) Доступ к самому массиву является потокобезопасным.

Как правильно обеспечить безопасность потоков при просмотре таблицы? Например, меня беспокоит то, что я могу изменить массив на более короткий непосредственно перед вызовом cellForRowAtIndexPath, что приведет к исключению NSRangeException.

Должен ли я ...

  1. Принудительно ли изменять массив только в основном потоке? (Кажется некрасивым.)
  2. Поддерживать массив теней и обновлять его в основном потоке с помощью наблюдения KVO?
  3. ??? Должно быть лучшее решение ...

Ответы [ 3 ]

6 голосов
/ 02 декабря 2008

Из вашего описания у вас действительно есть ДВА различных набора данных:

  • Фактические данные, как они существуют в вашей модели
  • Данные, отображаемые пользователю

Таким образом, у вас уже есть массив 'shadow' (виртуальная тень, которая может слишком сильно растягивать метафору). Я бы сказал, что вам лучше всего формализовать эту схему и сохранить массив «display», который изменяется только в основном потоке. В нем вы можете иметь объекты из вашего «реального» массива; поскольку они всего лишь указатели, вы не будете терять слишком много памяти.

Потоки зла.

3 голосов
/ 16 апреля 2011

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

dispatch_async(dispatch_get_main_queue(), ^{
                [array addObject:object];
                [tableView reloadData];
            });

Конечно, вы можете сделать намного более сложным с диспетчерским API, но он обрабатывает блокировки и все для вас. Определенно более элегантный, чем использование NSLock. Это работает только на iOS 4 или более поздней версии.

1 голос
/ 16 апреля 2011

У меня такая же ситуация. У меня есть массив объектов C ++, которые предоставляют информацию в виде таблицы.

Как говорил Бен, у меня также есть временный "теневой" массив, в который новая информация загружается через Интернет. Когда запрос завершен, я сверяю этот массив с массивом, поддерживающим представление таблицы, что довольно быстро. Вопрос в том, как защитить массив во время этой сверки.

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

Здесь есть похожий вопрос к вашему (и моему) здесь: Обновление UITableView с использованием потоков

но ответы ругают автора за то, что он слишком долго справлялся с его второстепенной операцией, вместо того, чтобы отвечать на его вопрос.

Я собираюсь использовать NSLock и получить его перед изменением массива и во всех методах делегатов UITableView, если у кого-то нет лучшей идеи.

...