Что лучше всего использовать для длительной операции, которая обновляет данные в отображаемом в данный момент виде таблицы iphone? - PullRequest
1 голос
/ 22 июня 2009

Фон

У меня есть табличное представление, отображающее около 8 разделов, каждый со своим собственным классом PlaceList, представляющим список объектов (реализация использует NSMutableArray). Всего около 200 объектов. Каждый участок соответствует тому, как далеко объект находится от текущего местоположения (например, в пределах 1 мили, в пределах 10, 25, 50 ... и т. Д.).

Время от времени мне нужно отвечать на асинхронные уведомления от CoreLocation, которые требуют, чтобы я пересчитал, к какому разделу принадлежит каждый объект, обновил расстояние для каждого объекта (который отображается в каждой ячейке), а также прибегнул к каждому списку, затем перезагрузите представление таблицы. Я также делаю эту операцию в viewWillAppear.

Внутри операции, которая выполняет обновление (метод PlaceList), я использовал @synchronized (self) на случай, если ОС вызывает его из более чем одного потока (я не использую для этого другой поток самостоятельно подарок). Однако в настоящее время эта операция приводит к тому, что пользовательский интерфейс время от времени «зависает», поэтому я ищу способы сделать это в своем собственном потоке.

Вопрос

  • Как лучше всего выполнить такую ​​длительную операцию над данными, поддерживающими табличное представление? Насколько я могу видеть, небезопасно выделять фоновый поток для выполнения операции, так как даже если я использую executeSelector для перезагрузки представления таблицы в основном потоке, когда это будет сделано, все же возможно, что пользователь коснется ячейки во время выполнения операции и данные не соответствуют отображению. А добавление любого вида блокировки просто уничтожило бы цель.

  • Отправляет ли пользовательский интерфейс и CoreLocation locationManager свои уведомления в одном потоке, т. Е. Можно ли безопасно обойтись без @synchronized (self) в PlaceList?

1 Ответ

3 голосов
/ 22 июня 2009

Вот мое понимание вашей проблемы. У вас есть большой список данных, и в какой-то момент он станет недействительным. Чтобы снова сделать его действительным, вы должны выполнить некоторую обработку, прежде чем сможете перекрасить таблицу.

Если это правильно, вот несколько вариантов.

1) Двойной буфер ваших данных. Пока вы отображаете что-то, что было «правильно», пользователь может нормально взаимодействовать с ним. Когда вы получите триггер для обработки данных, работайте с ним в фоновом режиме с копией, а когда он будет готов полностью перерисовать, обновите. Это обновление может быть резким и большим, но отображаемые данные всегда будут правильными или, по крайней мере, нормальными, а пользовательский интерфейс продолжает работать и не пугает пользователя.

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

AFAIK, приложение Facebook, похоже, делает это, также как и TwitterFon. По крайней мере, так оно и есть. Трудно сказать наверняка.

2) Загрузочный экран! Не весело, но это работает. Если вы знаете, что данные неверны, откройте полупрозрачную панель и попросите пользователя немного повиснуть.

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

...