4

sendAsynchronousRequestメソッドを呼び出しNSURLConnectionてデータをフェッチするメイン UI スレッドがあります。

[NSURLConnection sendAsynchronousRequest:[self request] 
 queue:[NSOperationQueue alloc] init
 completionHandler:
        ^(NSURLResponse *response, NSData *data, NSError *error)       
        {
            if (error)
            {
               //error handler 
            }
            else 
            {
               //dispatch_asych to main thread to process data.
            } 
        }];

これはすべて問題ありません。

ここでの私の質問は、エラー時に再試行機能を実装する必要があるということです。

  1. sendSynchronousRequestこれはバックグラウンド キューであるため、このブロックで実行し、再試行を呼び出すことができますか。
  2. または、メイン スレッドにディスパッチし、メイン スレッド ハンドルに再試行させます (sendAsynchronousRequest同じサイクルを呼び出して繰り返すことにより)。
4

1 に答える 1

1

を呼び出してリクエストを取得しています[self request]。がアトミック @property である場合request、またはそれ以外の場合はスレッド セーフである場合、非メイン スレッドから再試行を開始できなかった理由は考えられません。

または、呼び出しの前にリクエストのコピーをローカル変数に入れることもできます+sendAsynchronousRequest:queue:。それを行って完了ハンドラーで参照すると、暗黙的に保持[self request]され、一度だけ呼び出されます。

一般的に言えば、これはおそらく優れたパターンではありません。サービスがダウンしている場合、他のチェックがなければ、永遠に試行し続けます。次のようなことを試してみてください:

NSURLRequest* req = [self request];
NSOperationQueue* queue = [[NSOperationQueue alloc] init];
__block NSUInteger tries = 0;

typedef void (^CompletionBlock)(NSURLResponse *, NSData *, NSError *);    
__block CompletionBlock completionHandler = nil;

// Block to start the request
dispatch_block_t enqueueBlock = ^{
    [NSURLConnection sendAsynchronousRequest:req queue:queue completionHandler:completionHandler];
};

completionHandler = ^(NSURLResponse *resp, NSData *data, NSError *error) {
    tries++;
    if (error)
    {
        if (tries < 3)
        {
            enqueueBlock();
        }
        else
        {
            // give up
        }
    }
    else
    {
        //dispatch_asych to main thread to process data.
    }
};

// Start the first request
enqueueBlock();
于 2013-02-10T18:09:31.123 に答える