web-dev-qa-db-ja.com

NSURLSession for HTTPデータタスク(NSURLSessionDataTask)はバックグラウンドスレッドで実行されますか、それともキューを提供する必要がありますか?

NSURLSessionは、Appleが提供する新しくエレガントなAPIであるため、今日はNSURLConnectionを避けて使用し始めました。以前は、呼び出しNSURLRequestGCDブロックに入れて、バックグラウンドで実行していました。これが私が過去にした方法です:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    NSURLRequest *request = [NSURLRequest requestWithURL:
                             [NSURL URLWithString:@"www.stackoverflow.com"]];
    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
     *-----------------*/

    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) 
{
    NSDictionary *json = [NSJSONSerialization 
                          JSONObjectWithData:data options:0 error:nil];
    NSLog(@"%@", json);
}];
}

リクエストはバックグラウンドスレッド自体で実行されるのでしょうか、それともNSURLRequestの場合と同じ方法で独自のメカニズムを提供する必要があるのでしょうか?

16
NSPratik

いいえ、これをバックグラウンドキューにディスパッチするために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];
}
44
Rob