HTTP 数据任务 (NSURLSessionDataTask) 的 NSURLSession 是否在后台线程中运行,或者我们必须提供队列?
Does NSURLSession for HTTP data task (NSURLSessionDataTask) runs in background thread or we will have to provide the queue?
我现在开始使用 NSURLSession
时避免使用 NSURLConnection
,因为它是 Apple 提供的全新且优雅的 API。以前,我曾经将 call NSURLRequest
放在 GCD
块中以在后台执行它。这是我过去的做法:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSURL *url = [NSURL URLWithString:@"www.whosebug.com"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLResponse *response;
NSError *error;
NSData *data = [NSURLConnection sendSynchronousRequest:request
returningResponse:&response
error:&error];
if (error) {
// Handle error
return;
}
dispatch_async(dispatch_get_main_queue(), ^{
// Do something with the data
});
});
现在,我是这样使用的 NSURLSession
:
- (void)viewDidLoad
{
[super viewDidLoad];
/*-----------------*
NSURLSession
*-----------------*/
NSURL *url = [NSURL URLWithString:@"https://itunes.apple.com/search?term=apple&media=software"];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithURL:url
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
{
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data
options:0
error:nil];
NSLog(@"%@", json);
}];
}
我想知道,我的请求是在后台线程本身上执行,还是我必须提供我自己的机制,就像在 NSURLRequest
的情况下一样?
不,您不需要使用 GCD 将其分派到后台队列。事实上,因为后台线程上的完成块 运行s,恰恰相反,如果你需要那个块中的任何东西到主队列上的 运行(例如,模型对象的同步更新, UI 更新等),您必须自己手动将其分派到主队列。例如,假设您要检索结果列表并更新 UI 以反映这一点,您可能会看到如下内容:
- (void)viewDidLoad
{
[super viewDidLoad];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithURL:[NSURL URLWithString:@"https://itunes.apple.com/search?term=apple&media=software"] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
// this runs on background thread
NSError *error;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
// detect and handle errors here
// otherwise proceed with updating model and UI
dispatch_async(dispatch_get_main_queue(), ^{
self.searchResults = json[@"results"]; // update model objects on main thread
[self.tableView reloadData]; // also update UI on main thread
});
NSLog(@"%@", json);
}];
[dataTask resume];
}
我现在开始使用 NSURLSession
时避免使用 NSURLConnection
,因为它是 Apple 提供的全新且优雅的 API。以前,我曾经将 call NSURLRequest
放在 GCD
块中以在后台执行它。这是我过去的做法:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSURL *url = [NSURL URLWithString:@"www.whosebug.com"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLResponse *response;
NSError *error;
NSData *data = [NSURLConnection sendSynchronousRequest:request
returningResponse:&response
error:&error];
if (error) {
// Handle error
return;
}
dispatch_async(dispatch_get_main_queue(), ^{
// Do something with the data
});
});
现在,我是这样使用的 NSURLSession
:
- (void)viewDidLoad
{
[super viewDidLoad];
/*-----------------*
NSURLSession
*-----------------*/
NSURL *url = [NSURL URLWithString:@"https://itunes.apple.com/search?term=apple&media=software"];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithURL:url
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
{
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data
options:0
error:nil];
NSLog(@"%@", json);
}];
}
我想知道,我的请求是在后台线程本身上执行,还是我必须提供我自己的机制,就像在 NSURLRequest
的情况下一样?
不,您不需要使用 GCD 将其分派到后台队列。事实上,因为后台线程上的完成块 运行s,恰恰相反,如果你需要那个块中的任何东西到主队列上的 运行(例如,模型对象的同步更新, UI 更新等),您必须自己手动将其分派到主队列。例如,假设您要检索结果列表并更新 UI 以反映这一点,您可能会看到如下内容:
- (void)viewDidLoad
{
[super viewDidLoad];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithURL:[NSURL URLWithString:@"https://itunes.apple.com/search?term=apple&media=software"] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
// this runs on background thread
NSError *error;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
// detect and handle errors here
// otherwise proceed with updating model and UI
dispatch_async(dispatch_get_main_queue(), ^{
self.searchResults = json[@"results"]; // update model objects on main thread
[self.tableView reloadData]; // also update UI on main thread
});
NSLog(@"%@", json);
}];
[dataTask resume];
}