ASIHttp Синхронный запрос выполняет методы делегата после возврата - PullRequest
3 голосов
/ 08 июня 2011

Я пытаюсь загрузить файл с сервера.Мой код следующий.В методе didFinishLaunchingWithOptions я создаю новый поток, используя detachNewThreadSelector, который выполняет следующий код.

NSString *destPath = [self.home_dir_path stringByAppendingPathComponent:[NSString stringWithFormat:@"_%@",content_data_file_name]];
[ContentBO downloadFile:destPath  content_name:content_data_file_name];
if([self updatesAvailable]){
    //update content
}else{
    //launch app
}

Мой код для загрузки файла:

@try{
    NSString *url = [NSString stringWithFormat:@"%@/%@",ServerURL,content_name];
    NSLog(@"downloading URL is: %@",url);
    self.request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:[url stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding]]];
    [self.request setRequestMethod:@"GET"];
    [self.request setDownloadDestinationPath:destFilePath]; 
    NSLog(@"destination path is: %@",destFilePath);
    [self.request setTimeOutSeconds:30];

    [self.request setDelegate:self];
    [self.request startSynchronous];

    NSError *error = [self.request error];
    NSData *receivedData = nil;

    if (!error) {
        isSuccess = YES;
        self.responseStr = [request responseString];
        receivedData = [NSData dataWithData:[self.request responseData]];
    }
    else {
        isSuccess = NO;
        NSLog(@"The following error occurred: %@", error);
    }
}@catch(NSException *e){
    NSLog(@"exception occured.");
}

Что я понимаю в синхронном вызове, так это то, что это блокирующий вызов, и управление не должно опускаться ниже

[ContentBO downloadFile:destPath  content_name:content_data_file_name];

до тех пор, пока элемент управления не выйдет из метода requestFinished в ASIHTTPRequestDelegate.В моем случае происходит следующее: элемент управления одновременно выполняет код в requestFinished и ниже

[ContentBO downloadFile:destPath  content_name:content_data_file_name];

Но я не хочу, чтобы элемент управления опускался ниже [ContentBO downloadFile ...] до выхода из метода requestFinished.

Ответы [ 2 ]

1 голос
/ 08 июня 2011

Вызов делегата requestFinished выполняется в главном потоке асинхронно, и ваш код не выполняется в главном потоке, поэтому ожидается, что оба будут выполняться одновременно.

Однако, поскольку вы используете синхронные запросы, почему бы не удалить содержимое requestFinished и поместить код после строки 'startSyncronous'? Вы гарантированно завершили запрос, когда startSynchronous возвращает.

0 голосов
/ 01 января 2013

В одном из моих проектов приложение должно было выполнять интенсивную синхронизацию данных на стороне сервера.В этом процессе одна операция должна была начаться после успешного выполнения предыдущего процесса, и я использовал в этом синхронные запросы ASIHttp.Я столкнулся с той же проблемой, о которой вы упоминали, поэтому для ее решения я использовал NSCondiiton.Все это требует, чтобы вы заблокировали поток после вызова: [self.request startSynchronous] ;.Когда метод делегата запросов вызывается после выполнения запроса, введите команду signal , и будет выполнена следующая строка кода после оператора блокировки потока.Вот грубый пример:

//declare a pointer to NSCondition in header file: 
    NSCondition *threadlock;


-(id) init 
{
      threadlock = [[NSCondition alloc] init];  //release it in dealloc
}


-(void)downLoadFile 
{
  [thread lock];

  //your request code

  [self.request setDidFinishSelector:@selector(downLoadFileRequestDone:)];  
  [self.request setDidFailSelector:@selector(downLoadFileRequestWentWrong:)];
  [self.request startSynchronous];
  [thread wait];
  //the lines here will be executed after you issue a signal command in the request delegate method
  [thread unlock];
}

-(void) downLoadFileRequestDone:(ASIHTTPRequest *)request
 {
  [thread lock];
  //perform desire functionality
  //when you are done call:
  [thread signal];
  [thread unlock];
}

Это сработало идеально для меня ... надеюсь, это поможет.

...