如何在返回值之前等待异步请求返回数据

时间:2013-08-12 11:56:42

标签: objective-c nsurlconnection nsmutableurlrequest nsurlconnectiondelegate

我使用以下代码向网站发送异步请求:

NSMutableURLRequest *requestSiteToSendData = [NSMutableURLRequest requestWithURL:[[NSURL alloc]initWithString:@"www.example.com"] cachePolicy:NSURLRequestReloadIgnoringCacheData  timeoutInterval:30];
NSURLConnection *connectionToSiteToSendData = [[NSURLConnection alloc]initWithRequest:requestSiteToSendData delegate:self];

然后我使用NSURLConnectionDelegate中定义的以下方法在数据提取完成后获取和解析数据。

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    //parse 'data'
    NSString *parsedData = [self parseDataWithData:data];
}

然后在我发送异步请求的方法中,我返回parsedData。但是返回应该仅在数据提取完成之后发生,因此解析完成。我知道问题出现了,如果那就是我需要的,那么为什么我不使用同步请求。这是因为我不希望我的其他方法在后台加载时挂断。

4 个答案:

答案 0 :(得分:1)

快速回答:如果它是异步的,你不想等待异步方法。 其中一个最佳选择是:

  • 调用想要数据的对象应该将自己设置为运行异步方法的对象,而在didReceiveData中,调用一个处理新接收数据的updateData:(NSString *)parsedData方法

  • 调用该方法的对象应该使用KVO来观察运行异步方法的对象的属性的任何更改。

告诉我你是否需要更多信息。

答案 1 :(得分:0)

异步请求在单独的线程上运行,因此我们不必担心处理视图锁定。 如果要发送同步请求,则必须使用GCD来实现相同的目标。并且在同步请求中将不提供诸如发送/接收的数据等各种其他细节。

如果您的代码下一个状态依赖于响应请求时收到的数据,则同步请求很有用。

答案 2 :(得分:0)

您拥有此委托方法,该方法将在服务器成功完成所有下载后执行。使用此方法执行剩余的过程

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    // do something with the data
    // receivedData is declared as a method instance elsewhere
    NSLog(@"Succeeded! Received %d bytes of data",[receivedData length]);
}

好的,当收到所有数据时,会执行此方法。您应该做的是从-didReceiveData委托方法收集所有数据,然后使用它来解析此方法。

A must read document for you

答案 3 :(得分:0)

据我所知,您希望在网络通话完成后返回数据。所以我建议为webcall创建任何返回NSData的方法,并执行以下操作:

NSHTTPURLResponse* urlResponse = nil;
NSError *error = [[NSError alloc] init];  
NSData *responseData = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:&urlResponse error:&error];  

if ([urlResponse statusCode] >= 200 && [urlResponse statusCode] < 300) {
       // return responseData from here.
}
else {
        NSLog(@"%d",[urlResponse statusCode]);
        NSString *result = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
        NSLog(@"%@",result);

}

并且您不想挂断视图。所以在后台线程中调用此方法。像这样:

[self performSelectorInBackground:@selector(WebCallMethod) withObject:nil];

希望它能帮助!!