Могу ли я намеренно заблокировать цикл, чтобы дождаться завершения асинхронного обратного вызова? - PullRequest
0 голосов
/ 21 февраля 2009

Я пытаюсь сделать пакетную загрузку фотографий в моем приложении для iPhone. У меня есть один скрипт, который просматривает фотографии пользователя, а затем для каждой фотографии вызывает другой скрипт для загрузки.

Сценарий, который выполняет загрузку, должен вызвать обратный вызов сценария, который запускает каждую из фотографий пользователя, чтобы сигнализировать об успехе или неудаче. Это немного странно, но мне нужно получить возможность блокировать синхронный вызов внутри цикла, но в то же время сценарий загрузки является асинхронным.

Код очень сложный, поэтому я попытаюсь использовать псевдокод:

Первый сценарий:

foreach (photoNeedsUpload in users photos)

       upload the photo via Upload Script

callback hook: successOrFailureUploading (called back by the Upload Script)

Скрипт загрузки:

    1. Do the upload and then wait for NSURLRequest callbacks: 

    connectionDidFinishLoading, didFailWithError, etc., etc.

    2. Upon getting called back, in turn:
call back Script One appropriately with success/failure signal

Моя проблема в том, что я хотел бы иметь асинхронные обратные вызовы, чтобы я мог проверить состояние загрузки, но мне действительно нужно заблокировать каждую фотографию и ждать, пока она будет загружена.

Есть ли простой способ сделать что-то подобное? Должен ли я перевести поток в спящий режим или просто сделать синхронный вызов http? Если так, как проверить на успех?

Я признаю, что я не делал домашнее задание по дизайну, и мне начинает казаться, что я создал круговую проблему для себя!

Ответы [ 2 ]

2 голосов
/ 01 апреля 2009

Мне нужно было сделать что-то подобное. Я хотел синхронную загрузку, но мне нужны были некоторые методы асинхронной загрузки (в частности, обработка авторизации).

Я сделал это так

-(BOOL)getDataSynchronouslyFromAddress:(NSString*)address
{
    if (downloadRunning)
    {
        return NO;
    }

    downloadRunning=YES;
    downloadSucceeded=NO;

    NSURLConnection *connection=[self startConnectionWithAddress:address];
    if (!connection)
    {
        NSLog(@"no connection");
        downloadRunning=NO;
    }

    NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
    while (downloadRunning && [runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]);

    return downloadSucceeded;
}

когда загрузка закончилась, я просто установил соответствующим образом значение downloadSucceeded и установил downloadRunning на NO.

2 голосов
/ 21 февраля 2009

Ну, да, конечно, вы можете . Просто добавьте флаг, скажем, семафор, к вызывающей стороне; заставь его ждать этого флага.

Очистить флаг в обратном вызове. Бум, вот ты где.

Вопрос в следующем: Почему? Зачем идти на все эти неприятности; вместо этого просто запустите процесс синхронно. Тогда вам не нужен обратный звонок.

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

Вы уверены, что не хотите, чтобы колбэк установил флаг, чтобы сообщить вам, что работа сделана, и вернулся к ней?

Вы также можете посмотреть на шаблон Асинхронного жетона завершения.

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