21

我现在开始使用它NSURLSessionNSURLConnection因为它是 Apple 提供的一种新的优雅的 API。以前,我曾经将调用NSURLRequest放在GCD块中以在后台执行它。以下是我过去的做法:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    NSURL *url = [NSURL URLWithString:@"www.stackoverflow.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

4

1 回答 1

49

不,您不需要使用 GCD 将其分派到后台队列。事实上,因为完成块在后台线程上运行,正好相反,如果你需要该块中的任何东西在主队列上运行(例如,模型对象的同步更新、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];
}
于 2015-07-31T13:20:32.783 回答