Migrated from Grand Central Dispatch queue for mapping into an NSOperationQueue to enable KVO

This commit is contained in:
Blake Watters
2012-06-18 23:46:55 -04:00
parent c4841f10b6
commit 57e4e0933a
6 changed files with 31 additions and 55 deletions

View File

@@ -136,7 +136,8 @@ typedef void(^RKObjectLoaderDidLoadObjectsDictionaryBlock)(NSDictionary *diction
* includes Core Data specific mapping logic.
*/
@interface RKObjectLoader : RKRequest {
NSObject* _targetObject;
id _sourceObject;
id _targetObject;
}
/**
@@ -250,11 +251,11 @@ typedef void(^RKObjectLoaderDidLoadObjectsDictionaryBlock)(NSDictionary *diction
@property (nonatomic, retain) NSObject *targetObject;
/**
The Grand Central Dispatch queue to perform our parsing and object mapping
The operation queue to perform our parsing and object mapping
within. By default, object loaders will use the mappingQueue from the RKObjectManager
that created the loader. You can override this on a per-loader basis as necessary.
*/
@property (nonatomic, assign) dispatch_queue_t mappingQueue;
@property (nonatomic, retain) NSOperationQueue *mappingQueue;
///////////////////////////////////////////////////////////////////////////////////////////

View File

@@ -271,24 +271,22 @@
return [self mapResponseWithMappingProvider:mappingProvider toObject:self.targetObject inContext:RKObjectMappingProviderContextObjectsByKeyPath error:error];
}
- (void)performMappingInDispatchQueue
- (void)performMappingInOperationQueue
{
NSAssert(self.mappingQueue, @"mappingQueue cannot be nil");
dispatch_async(self.mappingQueue, ^{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
RKLogDebug(@"Beginning object mapping activities within GCD queue labeled: %s", dispatch_queue_get_label(self.mappingQueue));
[self.mappingQueue addOperationWithBlock:^{
RKLogDebug(@"Beginning object mapping activities within GCD queue labeled: %@", self.mappingQueue.name);
NSError *error = nil;
_result = [[self performMapping:&error] retain];
NSAssert(_result || error, @"Expected performMapping to return a mapping result or an error.");
if (self.result) {
[self processMappingResult:self.result];
} else if (error) {
[self performSelectorOnMainThread:@selector(didFailLoadWithError:) withObject:error waitUntilDone:NO];
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[self didFailLoadWithError:error];
}];
}
[pool drain];
});
}];
}
- (BOOL)canParseMIMEType:(NSString *)MIMEType
@@ -482,19 +480,6 @@
}
}
- (void)setMappingQueue:(dispatch_queue_t)newMappingQueue
{
if (_mappingQueue) {
dispatch_release(_mappingQueue);
_mappingQueue = nil;
}
if (newMappingQueue) {
dispatch_retain(newMappingQueue);
_mappingQueue = newMappingQueue;
}
}
// Proxy the delegate property back to our superclass implementation. The object loader should
// really not be a subclass of RKRequest.
- (void)setDelegate:(id<RKObjectLoaderDelegate>)delegate

View File

@@ -132,25 +132,26 @@ typedef enum {
/** @name Object Mapping Dispatch Queue */
/**
Returns the global default Grand Central Dispatch queue used for object mapping
Returns the global default operation queue queue used for object mapping
operations executed by RKObjectLoaders.
All object loaders perform their loading within a Grand Central Dispatch
queue. This provides control over the number of loaders that are performing
All object loaders perform their loading within an operation queue.
This provides control over the number of loaders that are performing
expensive operations such as JSON parsing, object mapping, and accessing Core
Data concurrently. The defaultMappingQueue is configured as the mappingQueue
for all RKObjectManager's created by RestKit, but can be overridden on a per
manager and per object loader basis.
By default, the defaultMappingQueue is configured as serial GCD queue.
By default, the defaultMappingQueue is configured with a maximumConcurrentOperationCount
of 1.
*/
+ (dispatch_queue_t)defaultMappingQueue;
+ (NSOperationQueue *)defaultMappingQueue;
/**
Sets a new global default Grand Central Dispatch queue for use in object mapping
Sets a new global default operation queue for use in object mapping
operations executed by RKObjectLoaders.
*/
+ (void)setDefaultMappingQueue:(dispatch_queue_t)defaultMappingQueue;
+ (void)setDefaultMappingQueue:(NSOperationQueue *)defaultMappingQueue;
/// @name Initializing an Object Manager
@@ -233,10 +234,10 @@ typedef enum {
@property (nonatomic, retain) RKManagedObjectStore *objectStore;
/**
The Grand Dispatch Queue to use when performing expensive object mapping operations
The operation queue to use when performing expensive object mapping operations
within RKObjectLoader instances created through this object manager
*/
@property (nonatomic, assign) dispatch_queue_t mappingQueue;
@property (nonatomic, retain) NSOperationQueue *mappingQueue;
/**
The Default MIME Type to be used in object serialization.

View File

@@ -31,7 +31,7 @@ NSString * const RKObjectManagerDidBecomeOnlineNotification = @"RKDidEnterOnline
// Shared Instances
static RKObjectManager *sharedManager = nil;
static dispatch_queue_t defaultMappingQueue = nil;
static NSOperationQueue *defaultMappingQueue = nil;
///////////////////////////////////
@@ -48,24 +48,26 @@ static dispatch_queue_t defaultMappingQueue = nil;
@synthesize networkStatus = _networkStatus;
@synthesize mappingQueue = _mappingQueue;
+ (dispatch_queue_t)defaultMappingQueue
+ (NSOperationQueue *)defaultMappingQueue
{
if (! defaultMappingQueue) {
defaultMappingQueue = dispatch_queue_create("org.restkit.ObjectMapping", DISPATCH_QUEUE_SERIAL);
defaultMappingQueue = [NSOperationQueue new];
defaultMappingQueue.name = @"org.restkit.ObjectMapping";
defaultMappingQueue.maxConcurrentOperationCount = 1;
}
return defaultMappingQueue;
}
+ (void)setDefaultMappingQueue:(dispatch_queue_t)newDefaultMappingQueue
+ (void)setDefaultMappingQueue:(NSOperationQueue *)newDefaultMappingQueue
{
if (defaultMappingQueue) {
dispatch_release(defaultMappingQueue);
[defaultMappingQueue release];
defaultMappingQueue = nil;
}
if (newDefaultMappingQueue) {
dispatch_retain(newDefaultMappingQueue);
[newDefaultMappingQueue retain];
defaultMappingQueue = newDefaultMappingQueue;
}
}
@@ -426,19 +428,6 @@ static dispatch_queue_t defaultMappingQueue = nil;
self.client.router = router;
}
- (void)setMappingQueue:(dispatch_queue_t)newMappingQueue
{
if (_mappingQueue) {
dispatch_release(_mappingQueue);
_mappingQueue = nil;
}
if (newMappingQueue) {
dispatch_retain(newMappingQueue);
_mappingQueue = newMappingQueue;
}
}
#pragma mark - RKConfigrationDelegate
- (void)configureRequest:(RKRequest *)request

View File

@@ -204,7 +204,7 @@ static RKTestFactory *sharedFactory = nil;
+ (void)setUp
{
[RKObjectManager setDefaultMappingQueue:dispatch_queue_create("org.restkit.ObjectMapping", DISPATCH_QUEUE_SERIAL)];
[RKObjectManager setDefaultMappingQueue:nil];
[RKObjectMapping setDefaultDateFormatters:nil];
// Delete the store if it exists

View File

@@ -650,7 +650,7 @@
[userMapping mapAttributes:@"name", @"id", nil];
// Suspend the Queue to block object mapping
dispatch_suspend(objectManager.mappingQueue);
[objectManager.mappingQueue setSuspended:YES];
RKTestResponseLoader *responseLoader = [RKTestResponseLoader responseLoader];
[objectManager.mappingProvider setObjectMapping:userMapping forResourcePathPattern:@"/humans/1"];