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];
}