【问题标题】:ASIHttp Synchronous request is running delegate methods after returningASIHttp 同步请求在返回后正在运行委托方法
【发布时间】:2011-06-08 12:45:17
【问题描述】:

我正在尝试从服务器下载文件。我的代码如下。在 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];

直到控制超出 ASIHTTPRequestDelegate 的 requestFinished 方法。在我的情况下,发生的事情是控件同时在 requestFinished 及以下执行代码

[ContentBO downloadFile:destPath  content_name:content_data_file_name];

但我不希望控件在退出 requestFinished 方法之前低于 [ContentBO downloadFile...]。

【问题讨论】:

    标签: objective-c download asihttprequest


    【解决方案1】:

    requestFinished 委托调用在主线程上异步运行,而您的代码不在主线程上运行,因此预计两者会同时运行。

    但是,由于您使用的是同步请求,为什么不删除 requestFinished 的内容并将代码放在“startSyncronous”行之后?当 startSynchronous 返回时,您可以保证请求已经完成。

    【讨论】:

      【解决方案2】:

      在我的一个项目中,该应用程序必须进行繁重的服务器端数据同步。在那个过程中,一个操作应该在它的前一个过程成功执行后开始,而我正在使用 ASIHttp 同步请求。我遇到了你提到的同样的问题,所以我使用了 NSCondiiton 来解决它。它只要求您在调用后锁定线程: [self.request startSynchronous];。当请求执行后调用requests委托方法时,发出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];
      }
      

      它对我来说很完美......希望它会有所帮助。

      【讨论】:

        猜你喜欢
        • 2020-05-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-27
        • 2018-12-31
        • 1970-01-01
        相关资源
        最近更新 更多