NSURLConnection sendAsynchronousRequest具有重试功能

时间:2012-12-11 11:23:22

标签: nsurlconnection grand-central-dispatch

我的主UI线程调用了sendAsynchronousRequest NSURLConnection方法来获取数据。

[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并重复相同的循环)。

1 个答案:

答案 0 :(得分:1)

您是通过致电[self request]来获取请求的。如果request是一个原子@property,或者是其他线程安全的,我想不出你有什么理由不能从非主线程开始重试。

或者,您可以在+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();