mirror of
https://github.com/zhigang1992/RestKit.git
synced 2026-01-12 17:43:34 +08:00
Add workaround to avoid potential crash during execution of deletion operations on iOS 5. closes #1266
This commit is contained in:
@@ -326,10 +326,15 @@ extern NSString * const RKObjectMappingNestingAttributeKeyName;
|
||||
// Delete the object immediately if there are no connections that may make it valid
|
||||
if ([connections count] == 0 && RKDeleteInvalidNewManagedObject(mappingOperation.destinationObject)) return YES;
|
||||
|
||||
// Attempt to establish the connections and delete the object if its invalid once we are done
|
||||
/**
|
||||
Attempt to establish the connections and delete the object if its invalid once we are done
|
||||
|
||||
NOTE: We obtain a weak reference to the MOC to avoid a potential crash under iOS 5 if the MOC is deallocated before the operation executes. Under iOS 6, the object returns a nil `managedObjectContext` and the `performBlockAndWait:` message is sent to nil.
|
||||
*/
|
||||
NSOperationQueue *operationQueue = self.operationQueue ?: [NSOperationQueue currentQueue];
|
||||
__weak NSManagedObjectContext *weakContext = [(NSManagedObject *)mappingOperation.destinationObject managedObjectContext];
|
||||
NSBlockOperation *deletionOperation = [NSBlockOperation blockOperationWithBlock:^{
|
||||
[[(NSManagedObject *)mappingOperation.destinationObject managedObjectContext] performBlockAndWait:^{
|
||||
[weakContext performBlockAndWait:^{
|
||||
RKDeleteInvalidNewManagedObject(mappingOperation.destinationObject);
|
||||
}];
|
||||
}];
|
||||
|
||||
@@ -1363,4 +1363,35 @@
|
||||
expect([blake valueForKey:@"favoriteCat"]).to.equal([mapper.mappingResult.dictionary objectForKey:@"cat"]);
|
||||
}
|
||||
|
||||
- (void)testDeletionOperationAfterManagedObjectContextIsDeallocated
|
||||
{
|
||||
RKManagedObjectStore *managedObjectStore = [RKTestFactory managedObjectStore];
|
||||
NSManagedObjectContext *managedObjectContext = [managedObjectStore newChildManagedObjectContextWithConcurrencyType:NSPrivateQueueConcurrencyType];
|
||||
RKManagedObjectMappingOperationDataSource *dataSource = [[RKManagedObjectMappingOperationDataSource alloc] initWithManagedObjectContext:managedObjectContext cache:nil];
|
||||
|
||||
|
||||
NSDictionary *representation = @{ @"human": @{ @"name": @"Blake Watters", @"favoriteCatID": @(12345) }, @"cat": @{ @"railsID": @(12345) } };
|
||||
RKEntityMapping *catMapping = [RKEntityMapping mappingForEntityForName:@"Cat"
|
||||
inManagedObjectStore:managedObjectStore];
|
||||
RKCat *cat = [NSEntityDescription insertNewObjectForEntityForName:@"Cat" inManagedObjectContext:managedObjectContext];
|
||||
RKMappingOperation *mappingOperation = [[RKMappingOperation alloc] initWithSourceObject:representation destinationObject:cat mapping:catMapping];
|
||||
NSOperationQueue *operationQueue = [NSOperationQueue new];
|
||||
[operationQueue setSuspended:YES];
|
||||
dataSource.operationQueue = operationQueue;
|
||||
|
||||
id mockOperation = [OCMockObject partialMockForObject:mappingOperation];
|
||||
[[[mockOperation stub] andReturn:catMapping] objectMapping];
|
||||
[dataSource commitChangesForMappingOperation:mockOperation error:nil];
|
||||
|
||||
expect([operationQueue operationCount]).to.equal(1);
|
||||
dataSource = nil;
|
||||
managedObjectContext = nil;
|
||||
[operationQueue setSuspended:NO];
|
||||
|
||||
[operationQueue waitUntilAllOperationsAreFinished];
|
||||
// Create a operation queue
|
||||
// Create data source
|
||||
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user