Форум программистов, компьютерный форум CyberForum.ru

Как дождаться вызова метода connectionDidFinishLoading? - Objective-C

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 14, средняя оценка - 4.64
Vorona
Peace 2 all shining faces
 Аватар для Vorona
661 / 523 / 44
Регистрация: 05.03.2010
Сообщений: 1,270
09.09.2012, 19:37     Как дождаться вызова метода connectionDidFinishLoading? #1
здравствуйте! недавно начал разбираться со взаимодействием ios с веб-сервисом.
вобщем есть у меня синглтон класс - слой между контроллером и моделью, там я указываю несколько методов, с помощью которых контроллер обращается к моделе. В этом же классе создаю необходимые методы делегата для соединения с инетом и посылания запросов:
Objective-C
1
2
3
4
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error;
- (void)connectionDidFinishLoading:(NSURLConnection *)connection;

Проблема в том, что когда я пытаюсь получить json ответ с веб-сервиса и обработать его в каком-то из методов, то этот метод начинает работать так и не дождавшись connectionDidFinishLoading или connection:didFailWithError, т.е. я начинаю обрабатывать данные, которые еще не пришли.

Вопрос в том, как узнать или подождать пока все данные загрузятся, а именно как узнать что метод connectionDidFinishLoading был вызван?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
zulkis
 Аватар для zulkis
681 / 608 / 38
Регистрация: 13.01.2011
Сообщений: 1,724
09.09.2012, 21:06     Как дождаться вызова метода connectionDidFinishLoading? #2
Цитата Сообщение от Vorona Посмотреть сообщение
Проблема в том, что когда я пытаюсь получить json ответ с веб-сервиса и обработать его в каком-то из методов, то этот метод начинает работать так и не дождавшись connectionDidFinishLoading или connection:didFailWithError, т.е. я начинаю обрабатывать данные, которые еще не пришли.
Чтооо? Какой метод начинает работать?
Ну если вызывается Ваш внутренний метод обработки, смотрите какой именно callback метод сработал. А в чем именно проблема?

Добавлено через 26 минут
Цитата Сообщение от Vorona Посмотреть сообщение
Вопрос в том, как узнать или подождать пока все данные загрузятся, а именно как узнать что метод connectionDidFinishLoading был вызван?
Ну как бы если он вызовется - он вызвался, а если нет - то нет xD
Vorona
Peace 2 all shining faces
 Аватар для Vorona
661 / 523 / 44
Регистрация: 05.03.2010
Сообщений: 1,270
09.09.2012, 22:38  [ТС]     Как дождаться вызова метода connectionDidFinishLoading? #3
Цитата Сообщение от zulkis Посмотреть сообщение
Чтооо? Какой метод начинает работать?
один из тех, что связывают контроллер с моделью, к примеру контроллер просит достать всех работников и вывести их в tableView, для этого есть метод:
- (NSMutableArray*)allEmployees;
1. тут мы устанавливаем соединение по указанной url,
2. потом должны подождать пока вызовется метод connectionDidFinishLoading,
3. теперь зная, что все данные загружены с веб-ресурса и операция прошла успешно, мы их обрабатываем и возвращаем массив объектов, которые будут выведены в tableView

вот незадача со 2 пунктом, а именно с тем, чтобы дождаться выполнения connectionDidFinishLoading и только потом продолжать работу

хорошо, может по-другому задать вопрос: можете ли вы привести пример работы класса с несколькими различными запросами,
где обработка данных происходит не в методе connectionDidFinishLoading, а в других внутренних методах?
zulkis
 Аватар для zulkis
681 / 608 / 38
Регистрация: 13.01.2011
Сообщений: 1,724
10.09.2012, 07:25     Как дождаться вызова метода connectionDidFinishLoading? #4
Я просто проблемы не вижу - connectionDidFinishLoading это всего лишь callback метод. Если Вы хотите его использовать в контроллере, будьте готовы как то сравнивать какой именно запрос выполнился, а затем уже парсить по разному его ответ.

По мне так намного удоблее всю эту "бадягу" с делегатовскими методами urlConnection'a обернуть как в AFNetworking. То есть каждый раз создается NSOperation в отдельном потоке, туда инкапсулируется NSURLRequest, который передается в NSURLConnection, и в этот же класс инкапсулируются блоки успешной\неудачной отбработки запроса. В итоге у Вас будет абсолютно чистый высокоуровневый код.
А свои блоки Вы и будете вызывать уже из вышего низкоуровнего класса NSOperation, который и занимается тем, что отслеживает состояние запроса.

Скачайте с гитхаба AFNetworking, покопайтесь.
Vorona
Peace 2 all shining faces
 Аватар для Vorona
661 / 523 / 44
Регистрация: 05.03.2010
Сообщений: 1,270
10.09.2012, 19:00  [ТС]     Как дождаться вызова метода connectionDidFinishLoading? #5
спасибо! наверное я что-то недопонял, действительно, гляну, как это в AFNetworking делается)

Добавлено через 7 часов 36 минут
ура, вроде как разобрался.
описанный ниже метод будет выглядеть не так:
Objective-C
1
- (NSMutableArray*)allEmployees;
а так (или может граммотнее по-другому его назвать...):
Objective-C
1
- (void)allEmployeesWithCallback:(void(^)(NSMutableArray*))callbackBlock;
в блоке в контроллере мы просто укажем поведение колбека (обновить tableView, присвоить свежие данные локальной переменной и т.д.).
т.е. теперь когда контроллер просит вернуть список сущностей, он просто получает его, когда весь список будет готов; и вроде основной поток не тормозит и все на месте вовремя.
сам блок будет вызываться в методе connectionDidFinishLoading: и ему будет передан обработанный массив объектов,
так же в методе connectionDidFinishLoading: в свитче будем просматривать, какой именно конекшн создан и на основе этого работать с нужным нам колбеком и парсить для него данные
zulkis
 Аватар для zulkis
681 / 608 / 38
Регистрация: 13.01.2011
Сообщений: 1,724
10.09.2012, 20:55     Как дождаться вызова метода connectionDidFinishLoading? #6
Поведение Вы описали верно, только метод с названием
Objective-C
1
- (void)allEmployeesWithCallback:(void(^)(NSMutableArray*))callbackBlock;
Прямо просится из контроллера в модель типа Employee, и блок будет возвращать уже NSMutableArray готовых Employee.
А при вызове этого метода в модели, будет вызван метод у класса, отвечающего за работу с web api, который в свою очередь тоже примет блок, а в нем будет возвращен JSON, который модель распарсит и вернет в контроллер массив объектов.
И обязательно добавляйте в возвращаемые переменные блока NSError - очень удобно. Если на каком то уровне возникла ошибка - там создается NSError и через все уровни абстрактного "получения" данных, Вам прокинется этот error до самого контроллера(в Вашем случае).
Vorona
Peace 2 all shining faces
 Аватар для Vorona
661 / 523 / 44
Регистрация: 05.03.2010
Сообщений: 1,270
10.09.2012, 23:08  [ТС]     Как дождаться вызова метода connectionDidFinishLoading? #7
Цитата Сообщение от zulkis Посмотреть сообщение
только метод с названием
- (void)allEmployeesWithCallbackvoid(^)(NSMutableArray*))callbackBlock;
Прямо просится из контроллера в модель типа Employee
а он и не в контроллере, этот метод и остальные, которые обращаются к моделе, принадлежат синглтон-классу-прослойке, в котором я инкапсулирую, как именно я буду обращаться к моделе: sqlite, core data, file system, web-service и т.д.
и за NSError спасибо
zulkis
 Аватар для zulkis
681 / 608 / 38
Регистрация: 13.01.2011
Сообщений: 1,724
11.09.2012, 01:17     Как дождаться вызова метода connectionDidFinishLoading? #8
Цитата Сообщение от Vorona Посмотреть сообщение
а он и не в контроллере, этот метод и остальные, которые обращаются к моделе, принадлежат синглтон-классу-прослойке, в котором я инкапсулирую, как именно я буду обращаться к моделе: sqlite, core data, file system, web-service и т.д.
и за NSError спасибо
Ну тем более. 1 класс будет обо всем знать. В модель этот метод.
Vorona
Peace 2 all shining faces
 Аватар для Vorona
661 / 523 / 44
Регистрация: 05.03.2010
Сообщений: 1,270
11.09.2012, 16:48  [ТС]     Как дождаться вызова метода connectionDidFinishLoading? #9
грррр
все было отлично до того момента когда оказалось, что в контроллере методы любят инициализировать другие вьюКонтроллеры передавая им в качестве аргумента коллекции или объекты, которые должны быть получены в качестве http запроса (например для вызова модальных вьюшек)
получается такая конетель, что в один вьюКонтроллер колбеком возвращаются данные и они же должны передаваться в другой вьюКонтроллер, т.е. второй вьюКонтроллер должен тоже как бы ждать, пока они придут и выходит такая вот цепочка зависимости одного от другого

можете посоветовать, как справиться с этой проблемой?
не хочется везде напихивать кучу колбеков чтобы все работало, может есть вариант получше?
zulkis
 Аватар для zulkis
681 / 608 / 38
Регистрация: 13.01.2011
Сообщений: 1,724
11.09.2012, 17:54     Как дождаться вызова метода connectionDidFinishLoading? #10
Ну если Вы мне исходники кинете, а мне будет нечем заняться, я отпишу где и что коряво.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
12.09.2012, 19:48     Как дождаться вызова метода connectionDidFinishLoading?
Еще ссылки по теме:

Objective-C Переопределение метода в сабклассе делегата
Objective-C Как из одного метода обратиться к переменной другого?
Вызов метода базового класса, если он был переопределён в наследнике Objective-C

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Vorona
Peace 2 all shining faces
 Аватар для Vorona
661 / 523 / 44
Регистрация: 05.03.2010
Сообщений: 1,270
12.09.2012, 19:48  [ТС]     Как дождаться вызова метода connectionDidFinishLoading? #11
спасибо, уже сам разобрался
и еще, была одна непонятка, если кому понадобится, в том месте (если следовать советам документации), где мы создаем конекшн
Objective-C
1
2
3
4
5
6
if (self.connection) {
    self.receivedData = [[NSMutableData data] retain];
    // ...
} else {
    // handle error
}
часто вылетало приложение и я получал ошибки EXC_BAD_ACCESS и SIGABRT во второй строке, где присваиваем receivedData
как оказалось, после того, как освободить receivedData, нужно присвоить ей nil, ну и для connection тоже можно повторить такую же процудуру, тогда проблема исчезла
Objective-C
1
2
[_receivedData release];
[self setReceivedData:nil];
Yandex
Объявления
12.09.2012, 19:48     Как дождаться вызова метода connectionDidFinishLoading?
Ответ Создать тему
Опции темы

Текущее время: 05:39. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru