Как приостановить / остановить функцию, пока запрос SOAP не будет завершен - PullRequest
2 голосов
/ 15 ноября 2010

РЕДАКТИРОВАТЬ: у меня проблема в том, что я использую календарь TapKu, поэтому я полагаюсь на предоставленных делегатов. Вот проблема:

- (NSArray*) calendarMonthView:(TKCalendarMonthView*)monthView marksFromDate:(NSDate*)startDate toDate:(NSDate*)lastDate{

//SOAP Request has NSURLConnection which runs asychonrous delegate methods.
//SOAP Request will return before the data array has been populated
[self SOAPRequest:startDate];

//i need to do something like this, however the SOAPRequest will return and get stuck into the loop instead of the asychronos delegates firing
//therefore i can never set bGettingData to NO.
int iWait;
while (bGettingData) {
    iWait++;
}

return dataArray;

}

Здравствуйте,

В приложении, которое я создаю, я полагаюсь на запросы SOAP для извлечения данных, разбора XML и заполнения массива.

Проблема, с которой я столкнулся, заключается в том, что при проверке массива он пуст, поскольку SOAP-запрос еще не завершен. Как я могу остановить выполнение моего кода до тех пор, пока не завершится запрос SOAP, и возобновить код? Можно ли это сделать с помощью обратного вызова или потоков?

Спасибо

Ответы [ 5 ]

1 голос
/ 15 ноября 2010

Не останавливайтесь временно, не спите и не ждите, вместо этого просто выйдите / выйдите / вернитесь из текущей процедуры / функции / метода.

Разбейте ваши текущие «вещи» на несколько фрагментов кода, каждый из которых имеет свой собственный метод.

Используйте последующие методы, чтобы делать все, что будет дальше, и вызовите этот метод в подпрограмме завершения вашего асинхронного сетевого / SOAP-запроса.

По сути, ваша проблема в том, что вы все еще думаете с точки зрения процедурного кодирования. Правильная парадигма заключается в использовании событийно-ориентированного кодирования: пусть ОС вызывает ваш код, а не заставляет ваш код вызывать ОС и ждать.

0 голосов
/ 09 октября 2013

Это действительно возможно, например, для представления календаря дня измените _refreshDataPageWithAtIndex так:

- (void) _refreshDataWithPageAtIndex:(NSInteger)index{

    UIScrollView *sv = self.pages[index];
    TKTimelineView *timeline = [self _timelineAtIndex:index];


    CGRect r = CGRectInset(self.horizontalScrollView.bounds, HORIZONTAL_PAD, 0);
    r.origin.x = self.horizontalScrollView.frame.size.width * index + HORIZONTAL_PAD;
    sv.frame = r;



    timeline.startY = VERTICAL_INSET;

    for (UIView* view in sv.subviews) {
        if ([view isKindOfClass:[TKCalendarDayEventView class]]){
            [self.eventGraveYard addObject:view];
            [view removeFromSuperview];
        }
    }

    if(self.nowLineView.superview == sv) [self.nowLineView removeFromSuperview];
    if([timeline.date isTodayWithTimeZone:self.timeZone]){

        NSDate *date = [NSDate date];
        NSDateComponents *comp = [date dateComponentsWithTimeZone:self.timeZone];

        NSInteger hourStart = comp.hour;
        CGFloat hourStartPosition = hourStart * VERTICAL_DIFF + VERTICAL_INSET;

        NSInteger minuteStart = round(comp.minute / 5.0) * 5;
        CGFloat minuteStartPosition = roundf((CGFloat)minuteStart / 60.0f * VERTICAL_DIFF);

        CGRect eventFrame = CGRectMake(self.nowLineView.frame.origin.x, hourStartPosition + minuteStartPosition - 5, NOB_SIZE + self.frame.size.width - LEFT_INSET, NOB_SIZE);
        self.nowLineView.frame = eventFrame;
        [sv addSubview:self.nowLineView];

    }

    if(!self.dataSource) return;

    timeline.events = [NSMutableArray new];
    [self.dataSource calendarDayTimelineView:self eventsForDate:timeline.date andEvents:timeline.events success:^{
        [timeline.events sortUsingComparator:^NSComparisonResult(TKCalendarDayEventView *obj1, TKCalendarDayEventView *obj2){
            return [obj1.startDate compare:obj2.startDate];
        }];

        [self _realignEventsAtIndex:index];
        if(self.nowLineView.superview == sv)
            [sv bringSubviewToFront:self.nowLineView];
    }];
}

, а затем измените функцию eventsForDate, чтобы она выглядела следующим образом:

- (void) calendarDayTimelineView:(TKCalendarDayView*)calendarDayTimeline eventsForDate:(NSDate *)eventDate andEvents:(NSMutableArray *)events success:(void (^)())success {

    [Model doSomethingAsync andSuccess:^(NSArray *classes) {

        // .. Add stuff to events..

        success();
    }];
}

Я предполагаю, что шаблон для других элементов управления очень похож. Предполагается, что вы ожидаете продолжения процесса форматирования / компоновки, пока не получите свои данные.

0 голосов
/ 21 января 2011

К сожалению, при использовании календаря TapKu вы не можете асинхронно загружаться из базы данных через SOAP. Вы должны синхронно загружать календарь, потому что это не способ обновить представление календаря после завершения загрузки данных. Если у вас более 40 записей в месяц, это создаст огромную задержку в 5-6 секунд.

0 голосов
/ 15 ноября 2010

Вы действительно хотите подождать, пока ответ не будет завершен - обратный вызов обычно самый простой. Как именно зависит от используемой вами библиотеки / языка программирования (см. Выше в javascript ,jective C, вы написали код вручную или начали с примера).

Ознакомьтесь с ответами на пошаговое руководство по запросу SOAP для Iphone - например, http://macresearch.org/interacting-soap-based-web-services-cocoa-part-1 и http://brismith66.blogspot.com/2010/05/iphone-development-accesing-soap.html. или выполните https://developer.omniture.com/node/321 - которое просто ждет до ответ полностью получен.

0 голосов
/ 15 ноября 2010
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...