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

Objective-C

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

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

09.09.2012, 19:37. Просмотров 1744. Ответов 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 был вызван?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
09.09.2012, 19:37     Как дождаться вызова метода connectionDidFinishLoading?
Посмотрите здесь:

Как из одного метода обратиться к переменной другого? - Objective-C
Как в методе print вывести переменную f из метода SetC? -(void) setC: (float) f{ celc=(f-32)/1.8f; } -(void) print { ...

Вызов метода Obj-C - Objective-C
.h файл + (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize; .m файл + (UIImage...

Прерываем выполнение метода - Objective-C
Добрый день! Совсем недавно начал программировать на cocoa touch. До этого ни когда, ни на чем не программировал. Но вот сейчас уже имею...

Переменные внутри метода - Objective-C
Заметил такую вещь, что внутри метода создают временную переменную и присваивают ей значение уже существующей переменной, например есть...

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

Переопределение метода в сабклассе делегата - Objective-C
Сабж. Есть класс1, реализует некий метод некого протокола. Как в классе 2(наследник класса1) переопределить этот метод (не считая категории...

Вызов метода с возвратом значения - Objective-C
Есть метод: +(NSString*)outputString:(NSString*)inputString { //Какой-то код } Как его вызвать?

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
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
667 / 529 / 45
Регистрация: 05.03.2010
Сообщений: 1,273
09.09.2012, 22:38  [ТС]     Как дождаться вызова метода connectionDidFinishLoading? #3
Цитата Сообщение от zulkis Посмотреть сообщение
Чтооо? Какой метод начинает работать?
один из тех, что связывают контроллер с моделью, к примеру контроллер просит достать всех работников и вывести их в tableView, для этого есть метод:
- (NSMutableArray*)allEmployees;
1. тут мы устанавливаем соединение по указанной url,
2. потом должны подождать пока вызовется метод connectionDidFinishLoading,
3. теперь зная, что все данные загружены с веб-ресурса и операция прошла успешно, мы их обрабатываем и возвращаем массив объектов, которые будут выведены в tableView

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

хорошо, может по-другому задать вопрос: можете ли вы привести пример работы класса с несколькими различными запросами,
где обработка данных происходит не в методе connectionDidFinishLoading, а в других внутренних методах?
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
667 / 529 / 45
Регистрация: 05.03.2010
Сообщений: 1,273
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
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
667 / 529 / 45
Регистрация: 05.03.2010
Сообщений: 1,273
10.09.2012, 23:08  [ТС]     Как дождаться вызова метода connectionDidFinishLoading? #7
Цитата Сообщение от zulkis Посмотреть сообщение
только метод с названием
- (void)allEmployeesWithCallbackvoid(^)(NSMutableArray*))callbackBlock;
Прямо просится из контроллера в модель типа Employee
а он и не в контроллере, этот метод и остальные, которые обращаются к моделе, принадлежат синглтон-классу-прослойке, в котором я инкапсулирую, как именно я буду обращаться к моделе: sqlite, core data, file system, web-service и т.д.
и за NSError спасибо
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
667 / 529 / 45
Регистрация: 05.03.2010
Сообщений: 1,273
11.09.2012, 16:48  [ТС]     Как дождаться вызова метода connectionDidFinishLoading? #9
грррр
все было отлично до того момента когда оказалось, что в контроллере методы любят инициализировать другие вьюКонтроллеры передавая им в качестве аргумента коллекции или объекты, которые должны быть получены в качестве http запроса (например для вызова модальных вьюшек)
получается такая конетель, что в один вьюКонтроллер колбеком возвращаются данные и они же должны передаваться в другой вьюКонтроллер, т.е. второй вьюКонтроллер должен тоже как бы ждать, пока они придут и выходит такая вот цепочка зависимости одного от другого

можете посоветовать, как справиться с этой проблемой?
не хочется везде напихивать кучу колбеков чтобы все работало, может есть вариант получше?
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?
Еще ссылки по теме:

Переопределение метода только в iOS >= 7.0 - Objective-C
Такое возможно ? К примеру у меня есть класс, в нем метод - (void)drawRect:(CGRect)rect { .... } В iOS < 7.0 он вообще...

Запуск метода с параметрами в новом потоке - Objective-C
Стандартная ситуация, есть формочка, нажимаем кнопку, запускается сложная операция, форма подвисает, решение - вывести этот процесс в...

Вызов метода базового класса, если он был переопределён в наследнике - Objective-C
Здравствуйте! Подскажите, пожалуйста, как вызвать метод базового класса из объекта наследника, который уже переопределил метод базового...

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

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


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

Или воспользуйтесь поиском по форуму:
Vorona
Peace 2 all shining faces
667 / 529 / 45
Регистрация: 05.03.2010
Сообщений: 1,273
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?
Ответ Создать тему
Опции темы

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