Fixed issue with order dependence in Core Data connections. fixes #173

Since OM 2.0 connection of relationships happened during the object mapping operation
instead of aggregately at the end of the process. In this commit, we have introduced a lightweight
queue for deferring portions of the mapping operation until a larger aggregate mapping has completed.

The changes are as follows:
* Introduced RKMappingOperationQueue for queueing portions of mapping. This is a synchronous queue modeled off
of NSOperationQueue that does NOT use threading (for Core Data friendliness).
* RKObjectMappingOperation now has a RKMappingOperationQueue queue property that defaults to nil
* RKObjectMappingOperation instances built via RKObjectMapper will has a mapping operation queue
assigned to the property.
* If a queue is present, RKManagedObjectMappingOperation will use it to defer the connection of relationships.
* At the end of an RKObjectMapper process, the mapping operation queue used by all mapping operations created
during the process will be executed. This allows all relationships to be connected after all object creation
has completed.

The queue is general purpose, though currently only used for the connection of relationships.
This commit is contained in:
Blake Watters
2011-09-20 12:02:50 -04:00
parent 91a6e9423e
commit 70c73f2981
17 changed files with 246 additions and 22 deletions

View File

@@ -44,6 +44,7 @@
_sourceObject = [object retain];
_mappingProvider = mappingProvider;
_errors = [NSMutableArray new];
_operationQueue = [RKMappingOperationQueue new];
}
return self;
@@ -52,6 +53,7 @@
- (void)dealloc {
[_sourceObject release];
[_errors release];
[_operationQueue release];
[super dealloc];
}
@@ -207,7 +209,8 @@
RKObjectMappingOperation* operation = [RKObjectMappingOperation mappingOperationFromObject:mappableObject
toObject:destinationObject
withMapping:mapping];
withMapping:mapping];
operation.queue = _operationQueue;
BOOL success = [operation performMapping:&error];
if (success) {
if ([self.delegate respondsToSelector:@selector(objectMapper:didMapFromObject:toObject:atKeyPath:usingMapping:)]) {
@@ -301,6 +304,10 @@
}
}
// Allow any queued operations to complete
NSLog(@"The following operations are in the queue: %@", _operationQueue.operations);
[_operationQueue waitUntilAllOperationsAreFinished];
if ([self.delegate respondsToSelector:@selector(objectMapperDidFinishMapping:)]) {
[self.delegate objectMapperDidFinishMapping:self];
}