Как уведомить UITableViewController о том, что данные готовы к отображению?

У меня есть UITableViewController , о котором я хотел бы уведомить, когда данные соответствующей модели будут готовы к отображению. . Проблема в том, что эти данные извлекаются из веб-службы, и запрос может занять до нескольких секунд. В настоящее время я получаю данные синхронно в основном потоке, что, конечно же, вызывает блокировку моего основного потока. Теперь я не хочу, чтобы мой контроллер ничего знал о загрузке данных из Интернета. Как я могу этого добиться. В настоящее время я думаю об использовании GCD и реализации такого метода, как -loadDataWithCallback: , и предоставления обратного вызова, который в случае успеха запускает [tableView reloadData] . Это хороший подход? Есть ли другие возможности сообщить контроллеру, что модель готова? Другая идея, которая у меня была, заключалась в использовании механизма делегирования и настройке контроллера в качестве делегата моей модели?

Подводя итог, что лучше: GCD с обратными вызовами или реализация собственного механизма делегирования?

Есть ли другие возможности?


Обновление : 24 июня 2011 г., 13:15 CET

Прочитав все ваши ответы, я пришел к выводу, что есть 3 возможных решения моей проблемы:

  1. Используйте NSNotifications и используйте NSURLConnection для реализации async. скачать

  2. Реализуйте собственный протокол и используйте механизм делегирования. Снова используйте NSURLConnection для реализации async. загрузка.

  3. Используйте синхронную загрузку в отдельной очереди GCD и используйте обратные вызовы.

Поскольку никто не поддерживает последнее решение, я хочу обсудить этот подход немного подробнее. После просмотра всего кода, который участвует в обработке уведомлений, я думаю, что GCD - лучший подход. Вместо согласования определенного уведомления, которое должно быть каким-то образом задокументировано, чтобы каждый разработчик знал об этом, я могу просто использовать обратный вызов. С одной стороны, это дает мне понятный интерфейс, подобный тому, который у меня был бы при использовании делегата, с другой стороны, это дает мне полную гибкость. Вы действительно думаете, что GCD слишком сложен для этого? Вот мой код:

- (void)loadRestaurantsWithCallback:(void (^)())callback
{
    dispatch_queue_t current_queue = dispatch_get_current_queue();
    dispatch_queue_t download_queue = dispatch_queue_create("Download queue", NULL);

    dispatch_async(download_queue, ^{
        self.restaurants = [self loadRestaurants];
        dispatch_async(current_queue, ^{ callback(); });
    });

    dispatch_release(download_queue);
}

Между прочим, мое приложение просто отображает меню различных столовых в моем университете.

В моем контроллере я просто делаю следующее:

if (![self.canteen hasRestaurants]) {
    [self.canteen loadRestaurantsWithCallback:^{
        [self.tableView reloadData];
    }];
}

Это работает как шарм. Что вы думаете об этом решении?


Обновление : 24 июня 2011 г., 16:30 CET

Существует четвертое решение этой проблемы, и, вероятно, это правильный путь, даже если он включает больше кода, чем Подход НОД.Вот что я придумал:

  1. Используйте NSURLConnection для асинхронной загрузки.

  2. Пусть ваша модель отвечает на обратные вызовы, отправленные экземпляром NSURLConnection .

  3. Используйте Кодирование значения ключа и Наблюдение за значением ключа .

В вашем контроллере вам просто нужно сделать следующее:

[self.model addObserver:self forKeyPath:@"method-name" options:0 context:NULL];

и

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    [self.tableView reloadData];
}
5
задан t6d 27 September 2011 в 18:11
поделиться