嗨,我是 ios 的初学者,当我们使用 NSURLRequest 调用服务时,我想知道当我们使用“同步请求”调用服务并以编程方式使用异步请求调用服务时会发生什么, 请以编程方式解释操作,我在下面使用该代码编写了一些代码解释同步和异步操作
- (void)viewDidLoad {
[super viewDidLoad];
NSURL *url = [NSURL URLWithString"http://api.kivaws.org/v1/loans/search.json?status=fundraising"];
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url];
[theRequest setHTTPMethod"GET"];
[theRequest setValue"application/json" forHTTPHeaderField"Accept"];
[theRequest setValue"application/json" forHTTPHeaderField"Content-Type"];
[theRequest setTimeoutInterval:5];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if(connection){
webData = [[NSMutableData alloc] init];
}
}
- (void)connectionNSURLConnection *)connection didReceiveResponseNSURLResponse *)response {
[webData setLength:0];
}
- (void)connectionNSURLConnection *)connection didReceiveDataNSData *)data {
[webData appendData:data];
}
- (void)connectionNSURLConnection *)connection didFailWithErrorNSError *)error {
NSLog(@"error is %@",[error localizedDescription]);
}
- (void)connectionDidFinishLoadingNSURLConnection *)connection {
NSString * allDataDictionbary = [[NSString alloc] initWithData:webData encoding:NSUTF8StringEncoding];
NSArray * responseString = [allDataDictionbary JSONValue];
NSLog(@"final respone dictionary%@",responseString);
}
在回答您的问题时,同步请求会阻塞调用它们的线程,直到请求完成。 (因此,通常不鼓励同步请求。)异步请求让当前线程在执行请求时继续执行(例如,继续响应用户与应用程序的交互;响应系统事件等)。这通常是可取的。
您的代码正在执行异步请求(这很好)。不过也有一些问题:
你不应该再使用 NSURLConnection
了。它已被弃用。使用 NSURLSession
。它实际上更简单,因为您通常不必编写那些委托(delegate)方法(除非您想要这样做,因为您有一些迫切需要这样做)。
有关NSURLSession
的更多信息,请参阅Using NSURLSession在 URL session 编程指南中。 或观看 WWDC 2013 视频 What's New in Foundation Networking一个很好的介绍。
你没有做一些错误处理。您正在检查基本错误(例如,没有网络),这非常好,但您没有考虑其他 Web 服务器错误,这些错误可能并不总是导致 NSError
对象,但可能只会导致200 以外的 HTTP 状态代码。我建议检查一下。
参见 RFC 2616 的第 10 节获取 HTTP 状态代码列表。
您正在设置 application/json
的 Content-Type
。但这不是 JSON 请求。 (当然,响应是 JSON,但请求不是。)通常你会使用 application/x-www-form-urlencoded
来处理这样的请求。
在您的代码片段中,您建议来自服务器的响应是 JSON,其中 NSArray
作为顶级对象。但顶层对象是 NSDictionary
。
您正在使用 JSONValue
。我不确定是哪个 JSON 库,但我们中的许多人只是使用内置的 NSJSONSerialization
Apple 提供的类。很久以前,在 Apple 提供 NSJSONSerialization
之前,我们会使用第三方库来解析 JSON,但现在不再需要了。
NSURLSession
发送请求的正确方式如下:
NSURL *url = [NSURL URLWithString"http://api.kivaws.org/v1/loans/search.json?status=fundraising"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod"GET"];
[request setValue"application/json" forHTTPHeaderField"Accept"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error != nil) {
NSLog(@"fundamental network error = %@", error);
return;
}
if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode];
if (statusCode != 200) {
NSLog(@"Warning; server should respond with 200 status code, but returned %ld", (long)statusCode);
}
}
NSError *parseError;
NSDictionary *responseObject = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];
if (responseObject) {
NSLog(@"responseObject = %@", responseObject);
} else {
NSLog(@"Error parsing JSON: %@", parseError);
NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"responseString = %@", responseString);
}
}];
[task resume];
// Note, you'll reach this portion of your code before the
// above `completionHandler` runs because this request runs
// asynchronously. So put code that uses the network response
// above, inside that `completionHandler`, not here.
关于ios - 什么是 diff b/w 同步和异步请求,如何以编程方式检查此操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34237161/
欢迎光临 OGeek|极客世界-中国程序员成长平台 (http://jike.in/) | Powered by Discuz! X3.4 |