LoginSignup
28
28

More than 5 years have passed since last update.

blocksによるコールバックのジレンマ

Last updated at Posted at 2013-02-08

なにか非同期のリクエストを送るメソッド呼び出しを行う場合、よくあるデザインとして、
完了をblocksで通知してくれるものがあります。
例えば、

    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://google.co.jp"]];
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {

    }];

のようなケースです。
シングルリクエストならこれでいいでしょう。
しかしながら、これをループさせたくなったとき、多くの人ははたと手が止まってしまうのではないでしょうか?
というのも、

    for(int i = 0 ; i < 10 ; ++i)
    {
        NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://google.co.jp"]];
        [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {

        }];
    }

というのは良くないことが目に見えているからです。
できれば1つずつ完了を待ってやりたいですね。

そこで登場するのが今回の肝、再帰呼び出し(線形反復)です。

- (void)downloadWithURLs:(NSArray *)urls iteration:(int)i
{
    if(urls.count <= i)
    {
        //done.
        NSLog(@"all done.");
        return;
    }
    NSLog(@"downloading...");
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urls[i]]];
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
        NSLog(@"downloading done.");
        [self downloadWithURLs:urls iteration:i + 1];
    }];
}

//呼び出し側
    NSArray *urls = @[@"http://google.co.jp", @"http://google.co.jp", @"http://google.co.jp"];
    [self downloadWithURLs:urls iteration:0];

これを実行すれば、以下の出力を得られます
2013-02-08 16:49:00.808 MultipleDownloadIdiom[11178:c07] downloading...
2013-02-08 16:49:00.942 MultipleDownloadIdiom[11178:c07] downloading done.
2013-02-08 16:49:00.942 MultipleDownloadIdiom[11178:c07] downloading...
2013-02-08 16:49:01.001 MultipleDownloadIdiom[11178:c07] downloading done.
2013-02-08 16:49:01.002 MultipleDownloadIdiom[11178:c07] downloading...
2013-02-08 16:49:01.082 MultipleDownloadIdiom[11178:c07] downloading done.
2013-02-08 16:49:01.083 MultipleDownloadIdiom[11178:c07] all done.

ちゃんとやりたいことが実現できています
少々アクロバティックではありますが、目的が達成できました。

28
28
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
28
28