Peace 2 all shining faces
674 / 535 / 85
Регистрация: 05.03.2010
Сообщений: 1,282
1

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

09.09.2012, 19:37. Показов 2587. Ответов 10
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
здравствуйте! недавно начал разбираться со взаимодействием 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 был вызван?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
09.09.2012, 19:37
Ответы с готовыми решениями:

Как формируется адрес вызова метода
Всем хай. Понимаю вопрос нубский. Но раньше никогда приложения под asp net .Net Framework никогда...

Проверить возможность вызова метода из другого метода
Всем привет. Тут возникла мысля, что было бы здорово отследить все возможные вызовы метода Foo()...

Дождаться завершения метода
Доброго времени суток! Проблема следующая. Имеется скоростная камера, которая включается следующим...

Возможности вызова метода во время выполнения а не компиляции - как это понимать
Помогите разобраться пожалуйста. Читаю C# Шилдта. В некоторых местах книги (а конкретно к примеру в...

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

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

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

хорошо, может по-другому задать вопрос: можете ли вы привести пример работы класса с несколькими различными запросами,
где обработка данных происходит не в методе connectionDidFinishLoading, а в других внутренних методах?
0
686 / 613 / 43
Регистрация: 13.01.2011
Сообщений: 1,722
10.09.2012, 07:25 4
Я просто проблемы не вижу - connectionDidFinishLoading это всего лишь callback метод. Если Вы хотите его использовать в контроллере, будьте готовы как то сравнивать какой именно запрос выполнился, а затем уже парсить по разному его ответ.

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

Скачайте с гитхаба AFNetworking, покопайтесь.
1
Peace 2 all shining faces
674 / 535 / 85
Регистрация: 05.03.2010
Сообщений: 1,282
10.09.2012, 19:00  [ТС] 5
спасибо! наверное я что-то недопонял, действительно, гляну, как это в AFNetworking делается)

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

можете посоветовать, как справиться с этой проблемой?
не хочется везде напихивать кучу колбеков чтобы все работало, может есть вариант получше?
0
686 / 613 / 43
Регистрация: 13.01.2011
Сообщений: 1,722
11.09.2012, 17:54 10
Ну если Вы мне исходники кинете, а мне будет нечем заняться, я отпишу где и что коряво.
0
Peace 2 all shining faces
674 / 535 / 85
Регистрация: 05.03.2010
Сообщений: 1,282
12.09.2012, 19:48  [ТС] 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];
0
12.09.2012, 19:48
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
12.09.2012, 19:48
Помогаю со студенческими работами здесь

Как персонифицировать описание ошибки вызова метода COM-объекта в скомпилированном приложении?
Здравствуйте! Пример. Вот такой код: Private Sub Form_Load() On Error GoTo ErrorHandler...

Сбой вызова метода из-за отсутствия в [System.Object[]] метода с именем "op_Division"
При разборе скрипта, найденного на просторах интернета (Создание пользовательского объекта),...

Как сделать так, чтобы при создании объектов,полю присваивалось значение после вызова метода и этот объект добавлялся в коллекцию
Пробовал через конструктор, ног ничего не получается public Tematic(string ck,ArrayList r ){ ...

Вызова метода по таймеру
Есть рабочий метод, реализовывающий изменение TextView по таймеру. Скопипастил его же, но для...

Проблема вызова метода COM объекта из VB
Помогите решить проблему. Я написал на С++ COM объект и при попытке вызвать его метод из VB,...

Действия до и после вызова метода
Подскажите, пожалуйста, по реализации. Дан класс 'ServiceBase', содержащий ссылки на некоторые...


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

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru