0

NSURLConnection 非同期リクエストの completionHandler として使用するブロックがあります。その主な仕事は、新しいリクエスト完了ハンドラーに同じブロックを使用して新しい非同期リクエストを生成することです。私がこれを行っているのは、一連の非同期呼び出しを並べてバックグラウンドで起動させるという別の問題を効果的に解決するためです。これは私たちにとって驚くほどうまく機能していますが、私が心配している警告があります。つまり、XCode は保持サイクルがあると認識しています。多分私は知っています、私は知りません。ここ数時間、ブロックについて学ぼうとしてきましたが、私のような再帰的な使用法についての説明は見つかりませんでした。警告には、「ブロックはキャプチャされたオブジェクトによって保持されます」と記載されています。

これまでのところ、保持サイクルはまさに私たちが望んでいるものであり、完了したらクリアするには、ブロック変数を無効にするだけであると推測しています。エラーが解消されるわけではありませんが、メモリ リークが発生したり、知らないうちにブラック マジックを実行したりしていない限り、問題はありません。誰でもこれに対処できますか?私はそれを正しく扱っていますか?そうでない場合、私は何をすべきですか?

void (^ __block handler)(NSURLResponse *, NSData *, NSError*);
handler = ^(NSURLResponse *response, NSData *data, NSError *error)
{
    [dataArray addObject:data];

    if (++currentRequestIndex < [requestsArray count])
    {

        if (error)
        {
            [delegate requestsProcessWithIdentifier:_identifier processStoppedOnRequestNumber:currentRequestIndex-1 withError:error];
            return;
        }

        [delegate requestsProcessWithIdentifier:_identifier completedRequestNumber:currentRequestIndex-1]; // completed previous request

        [NSURLConnection sendAsynchronousRequest:[requestsArray objectAtIndex:currentRequestIndex]
                                           queue:[NSOperationQueue mainQueue]
                               completionHandler:handler]; // HERE IS THE WARNING
    }
    else
    {
        [delegate requestsProcessWithIdentifier:_identifier completedWithData:dataArray];
        handler = nil;
    }
};
[NSURLConnection sendAsynchronousRequest:[requestsArray objectAtIndex:0]
                                   queue:[NSOperationQueue mainQueue]
                       completionHandler:handler];
4

2 に答える 2

0

handlerブロックをビュー コントローラー (または現在のクラス) のインスタンス変数に格納してみてください。

という名前のインスタンス変数を宣言するとします_hander

{
  void (^_handler)(NSURLResponse *, NSData *, NSError*);
}

コードを次のように変更します。

__weak __typeof(&*self)weakSelf = self;
_handler = ^(NSURLResponse *response, NSData *data, NSError *error)
{
  [dataArray addObject:data];

  if (++currentRequestIndex < [requestsArray count])
  {

    if (error)
    {
      [delegate requestsProcessWithIdentifier:_identifier processStoppedOnRequestNumber:currentRequestIndex-1 withError:error];
      return;
    }

    [delegate requestsProcessWithIdentifier:_identifier completedRequestNumber:currentRequestIndex-1]; // completed previous request

    __strong __typeof(&*self)strongSelf = weakSelf;
    [NSURLConnection sendAsynchronousRequest:[requestsArray objectAtIndex:currentRequestIndex]
                                       queue:[NSOperationQueue mainQueue]
                           completionHandler:strongSelf->_handler];
  }
  else
  {
    [delegate requestsProcessWithIdentifier:_identifier completedWithData:dataArray];
  }
};

[NSURLConnection sendAsynchronousRequest:[requestsArray objectAtIndex:0]
                                   queue:[NSOperationQueue mainQueue]
                       completionHandler:_handler];
于 2013-05-24T00:36:22.000 に答える
0
void (^handler)(NSURLResponse *, NSData *, NSError*);
typeof(handler) __block __weak weakHandler;
weakHandler = handler = ^(NSURLResponse *response, NSData *data, NSError *error)
{
    [dataArray addObject:data];

    if (++currentRequestIndex < [requestsArray count])
    {

        if (error)
        {
            [delegate requestsProcessWithIdentifier:_identifier processStoppedOnRequestNumber:currentRequestIndex-1 withError:error];
            return;
        }

        [delegate requestsProcessWithIdentifier:_identifier completedRequestNumber:currentRequestIndex-1]; // completed previous request

        [NSURLConnection sendAsynchronousRequest:[requestsArray objectAtIndex:currentRequestIndex]
                                           queue:[NSOperationQueue mainQueue]
                               completionHandler:weakHandler]; // HERE IS THE WARNING
    }
    else
    {
        [delegate requestsProcessWithIdentifier:_identifier completedWithData:dataArray];
    }
};
于 2013-05-24T19:43:45.283 に答える