我必须在经过许多网站后一次调用20个urlReqests我发现4个urlRequsts在下次接收请求后会遇到错误即超时错误。当我在循环中调用5个webservices时,首先4个webservices是执行和第5次获取超时错误。如何处理这种情况 任何帮助将不胜感激
答案 0 :(得分:3)
您可以使用NSOperationQueue执行此类任务。以下是示例代码 -
RequestManager.h的代码: -
#import <Foundation/Foundation.h>
@protocol RequestManagerDelegate <NSObject>
@optional
- (void)requestForURL:(NSURL *)url tag:(NSString *)tag type:(NSString *)type
didComplete:(NSData *)data;
- (void)requestForURL:(NSURL *)url tag:(NSString *)tag type:(NSString *)type
didFailWithError:(NSError *)error;
@end
@interface RequestManager : NSObject
+ (RequestManager *) instance;
- (void)requestForURL:(NSURL *)url tag:(NSString *)tag delegate:(id<RequestManagerDelegate >)delegate;
@end
RequestManager.m的代码: -
#import "RequestManager.h"
@interface RequestManager () {
NSOperationQueue *requestQueue;
}
@end
@implementation RequestManager
static RequestManager *singletonInstance = nil;
- (id)init {
if(self = [super init]) {
requestQueue = [[NSOperationQueue alloc] init];
requestQueue.maxConcurrentOperationCount = 2;//Here you can select maximum concurrent operations
}
return self;
}
+ (RequestManager *) instance {
@synchronized(self) {
if(!singletonInstance) {
singletonInstance = [[RequestManager alloc] init];
}
}
return singletonInstance;
}
- (void)requestForURL:(NSURL *)url tag:(NSString *)tag delegate:(id<RequestManagerDelegate >)delegate {
[requestQueue setSuspended:YES];
RequestOperation *newOperation = [[RequestOperation alloc] initWithURL:url tag:tag delegate:delegate];
newOperation.queuePriority = NSOperationQueuePriorityVeryHigh;
[requestQueue addOperation:newOperation];
NSArray *operations = requestQueue.operations;
long operationsCount = operations.count;
RequestOperation *operation;
NSOperationQueuePriority priority = NSOperationQueuePriorityVeryHigh;
for(long i = (operationsCount - 1); i >= 0; i--) {
operation = [operations objectAtIndex:i];
if((operation.isExecuting || operation.isCancelled || operation.isFinished) == NO) {
[operation setQueuePriority:priority];
priority = [self nextPriorityLowerThan:priority];
}
}
[requestQueue setSuspended:NO];
}
- (NSOperationQueuePriority)nextPriorityLowerThan:(NSOperationQueuePriority)priority {
NSOperationQueuePriority lowerPriority = NSOperationQueuePriorityVeryLow;
switch (priority) {
case NSOperationQueuePriorityVeryHigh:
lowerPriority = NSOperationQueuePriorityHigh;
break;
case NSOperationQueuePriorityHigh:
lowerPriority = NSOperationQueuePriorityNormal;
break;
case NSOperationQueuePriorityNormal:
lowerPriority = NSOperationQueuePriorityLow;
break;
case NSOperationQueuePriorityLow:
lowerPriority = NSOperationQueuePriorityVeryLow;
break;
default:
break;
}
return lowerPriority;
}
@end
现在RequestOperation.h - &gt;
#import <Foundation/Foundation.h>
@interface RequestOperation : NSOperation
@property(readonly, copy) NSURL *url;
@property(strong , readonly) NSString *tag;
@property(strong , readonly) id<RequestManagerDelegate > *delagate;
- (id)initWithURL:(NSURL *)url tag:(NSString *)tag delegate:(id<RequestManagerDelegate >) delegate;
@end
现在RequestOperation.m
#import "RequestOperation.h"
@interface RequestOperation ()
{
NSURLConnection *connection;
}
@property (nonatomic) long long int expectedContentLength;
@property (nonatomic, readwrite) NSError* error;
@property (nonatomic) BOOL isExecuting;
@property (nonatomic) BOOL isConcurrent;
@property (nonatomic) BOOL isFinished;
@end
@implementation RequestOperation
- (id)initWithURL:(NSURL *)url tag:(NSString *)tag delegate:(id<RequestManagerDelegate >) delegate{
if ((self=[super init])) {
_url = url;
_tag = tag;
_delagate=delagate;
}
return self;
}
- (void)start
{
NSURLRequest* request = [NSURLRequest requestWithURL:_url];
//handle here for your request type (post or get)
self.isExecuting = YES;
self.isConcurrent = YES;
self.isFinished = NO;
[[NSOperationQueue mainQueue] addOperationWithBlock:^
{
connection = [NSURLConnection connectionWithRequest:request delegate:self];
}];
}
- (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response {
return request;
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
}
- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse {
return cachedResponse;
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
self.isExecuting = NO;
self.isFinished = YES;
}
- (void)connection:(NSURLConnection*)connection didFailWithError:(NSError*)error
{
self.error = error;
self.isExecuting = NO;
self.isFinished = YES;
}
- (void)setIsExecuting:(BOOL)isExecuting
{
[self willChangeValueForKey:@"isExecuting"];
_isExecuting = isExecuting;
[self didChangeValueForKey:@"isExecuting"];
}
- (void)setIsFinished:(BOOL)isFinished
{
[self willChangeValueForKey:@"isFinished"];
_isFinished = isFinished;
[self didChangeValueForKey:@"isFinished"];
}
- (void)cancel
{
[super cancel];
[connection cancel];
self.isFinished = YES;
self.isExecuting = NO;
}
@end
我给了你我的代码,这就是我如何异步管理多个并发请求。你可以使用它非常有效。您可以在RequestManager.h中使用方法声明请求url,并可以使用委托来处理结果。