Implement support for cancellation and prioritization of response mapping operations using an operation queue global to all object request operations.

* Passes through cancellation from object request operation to HTTP request operation and response mapping operation. closes #993
* Performs all object mapping within an NSOperationQueue to enable constraining of mapping activities.
* Add default mapping queue with concurrency limit of 1 operation.
* Migrate deserialization of the response body into a serial dispatch queue to ensure that only one parse occurs at a time.
This commit is contained in:
Blake Watters
2012-10-20 00:13:48 -04:00
parent 0738f59231
commit 08110ca300
8 changed files with 181 additions and 52 deletions

View File

@@ -72,10 +72,24 @@ static NSIndexSet *RKObjectRequestOperationAcceptableMIMETypes()
@property (nonatomic, strong, readwrite) NSArray *responseDescriptors;
@property (nonatomic, strong, readwrite) RKMappingResult *mappingResult;
@property (nonatomic, strong, readwrite) NSError *error;
@property (nonatomic, strong) RKObjectResponseMapperOperation *responseMapperOperation;
@end
@implementation RKObjectRequestOperation
+ (NSOperationQueue *)responseMappingQueue
{
static NSOperationQueue *responseMappingQueue = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
responseMappingQueue = [NSOperationQueue new];
[responseMappingQueue setName:@"RKObjectRequestOperation Response Mapping Queue" ];
[responseMappingQueue setMaxConcurrentOperationCount:1];
});
return responseMappingQueue;
}
- (void)dealloc
{
#if !OS_OBJECT_USE_OBJC
@@ -174,17 +188,19 @@ static NSIndexSet *RKObjectRequestOperationAcceptableMIMETypes()
- (RKMappingResult *)performMappingOnResponse:(NSError **)error
{
// Spin up an RKObjectResponseMapperOperation
RKObjectResponseMapperOperation *mapperOperation = [[RKObjectResponseMapperOperation alloc] initWithResponse:self.HTTPRequestOperation.response
data:self.HTTPRequestOperation.responseData
responseDescriptors:self.responseDescriptors];
mapperOperation.targetObject = self.targetObject;
[mapperOperation start];
[mapperOperation waitUntilFinished];
if (mapperOperation.error) {
if (error) *error = mapperOperation.error;
self.responseMapperOperation = [[RKObjectResponseMapperOperation alloc] initWithResponse:self.HTTPRequestOperation.response
data:self.HTTPRequestOperation.responseData
responseDescriptors:self.responseDescriptors];
self.responseMapperOperation.targetObject = self.targetObject;
[self.responseMapperOperation setQueuePriority:[self queuePriority]];
[[RKObjectRequestOperation responseMappingQueue] addOperation:self.responseMapperOperation];
[self.responseMapperOperation waitUntilFinished];
if ([self isCancelled]) return nil;
if (self.responseMapperOperation.error) {
if (error) *error = self.responseMapperOperation.error;
return nil;
}
return mapperOperation.mappingResult;
return self.responseMapperOperation.mappingResult;
}
- (void)willFinish
@@ -196,6 +212,7 @@ static NSIndexSet *RKObjectRequestOperationAcceptableMIMETypes()
{
[super cancel];
[self.HTTPRequestOperation cancel];
[self.responseMapperOperation cancel];
}
- (void)execute