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

Objective-C

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 14, средняя оценка - 4.64
Vorona
Peace 2 all shining faces
668 / 530 / 45
Регистрация: 05.03.2010
Сообщений: 1,283
#1

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

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

здравствуйте! недавно начал разбираться со взаимодействием 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
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
09.09.2012, 19:37
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Как дождаться вызова метода connectionDidFinishLoading? (Objective-C):

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

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

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

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

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

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

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

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

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

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

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

Скачайте с гитхаба AFNetworking, покопайтесь.
1
Vorona
Peace 2 all shining faces
668 / 530 / 45
Регистрация: 05.03.2010
Сообщений: 1,283
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
zulkis
682 / 609 / 38
Регистрация: 13.01.2011
Сообщений: 1,724
10.09.2012, 20:55 #6
Поведение Вы описали верно, только метод с названием
Objective-C
1
- (void)allEmployeesWithCallback:(void(^)(NSMutableArray*))callbackBlock;
Прямо просится из контроллера в модель типа Employee, и блок будет возвращать уже NSMutableArray готовых Employee.
А при вызове этого метода в модели, будет вызван метод у класса, отвечающего за работу с web api, который в свою очередь тоже примет блок, а в нем будет возвращен JSON, который модель распарсит и вернет в контроллер массив объектов.
И обязательно добавляйте в возвращаемые переменные блока NSError - очень удобно. Если на каком то уровне возникла ошибка - там создается NSError и через все уровни абстрактного "получения" данных, Вам прокинется этот error до самого контроллера(в Вашем случае).
1
Vorona
Peace 2 all shining faces
668 / 530 / 45
Регистрация: 05.03.2010
Сообщений: 1,283
10.09.2012, 23:08  [ТС] #7
Цитата Сообщение от zulkis Посмотреть сообщение
только метод с названием
- (void)allEmployeesWithCallbackvoid(^)(NSMutableArray*))callbackBlock;
Прямо просится из контроллера в модель типа Employee
а он и не в контроллере, этот метод и остальные, которые обращаются к моделе, принадлежат синглтон-классу-прослойке, в котором я инкапсулирую, как именно я буду обращаться к моделе: sqlite, core data, file system, web-service и т.д.
и за NSError спасибо
0
zulkis
682 / 609 / 38
Регистрация: 13.01.2011
Сообщений: 1,724
11.09.2012, 01:17 #8
Цитата Сообщение от Vorona Посмотреть сообщение
а он и не в контроллере, этот метод и остальные, которые обращаются к моделе, принадлежат синглтон-классу-прослойке, в котором я инкапсулирую, как именно я буду обращаться к моделе: sqlite, core data, file system, web-service и т.д.
и за NSError спасибо
Ну тем более. 1 класс будет обо всем знать. В модель этот метод.
1
Vorona
Peace 2 all shining faces
668 / 530 / 45
Регистрация: 05.03.2010
Сообщений: 1,283
11.09.2012, 16:48  [ТС] #9
грррр
все было отлично до того момента когда оказалось, что в контроллере методы любят инициализировать другие вьюКонтроллеры передавая им в качестве аргумента коллекции или объекты, которые должны быть получены в качестве http запроса (например для вызова модальных вьюшек)
получается такая конетель, что в один вьюКонтроллер колбеком возвращаются данные и они же должны передаваться в другой вьюКонтроллер, т.е. второй вьюКонтроллер должен тоже как бы ждать, пока они придут и выходит такая вот цепочка зависимости одного от другого

можете посоветовать, как справиться с этой проблемой?
не хочется везде напихивать кучу колбеков чтобы все работало, может есть вариант получше?
0
zulkis
682 / 609 / 38
Регистрация: 13.01.2011
Сообщений: 1,724
11.09.2012, 17:54 #10
Ну если Вы мне исходники кинете, а мне будет нечем заняться, я отпишу где и что коряво.
0
Vorona
Peace 2 all shining faces
668 / 530 / 45
Регистрация: 05.03.2010
Сообщений: 1,283
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
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
12.09.2012, 19:48
Привет! Вот еще темы с ответами:

Разобрать синтаксис вызова метода - C#
Здравствуйте, подскажите что означает данный синтаксис вызова метода: Process.Start(new ProcessStartInfo(Application.ExecutablePath,...

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

Неправильная периодичность вызова метода по таймеру - Программирование Android
Есть необходимость запускать некую задачу в фоне по таймеру. Для этого я использовал следующий код //обновление по таймеру ...

Простой способ удаленного вызова метода - C#
Ребят можете привети пример кода для вызова метода в классе C# удаленно ? То есть есть программа сервер на которой есть некий класс...


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

Или воспользуйтесь поиском по форуму:
11
Yandex
Объявления
12.09.2012, 19:48
Ответ Создать тему
Опции темы

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