我正在尝试从服务器下载文件。我的代码如下。在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
}
我的downloadFile代码是:
@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 ...]。
答案 0 :(得分:1)
requestFinished委托调用是异步运行在主线程上的,并且你的代码没有在主线程上运行,因此预计两者都会同时运行。
但是,当您使用同步请求时,为什么不删除requestFinished的内容并将代码放在'startSyncronous'行之后?保证在startSynchronous返回时请求已完成。
答案 1 :(得分:0)
在我的一个项目中,应用程序必须执行繁重的服务器端数据同步。在该过程中,一个操作应该在成功执行它的前一个进程后启动,并且我正在使用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];
}
它对我来说很完美......希望它会有所帮助。