Reid
Reid

Reputation: 1129

Core Data multithreading--what am I doing wrong

I'll try to keep this brief but basically, I have an app that, in a certain mode, can near-continuously log location and other data, and snap photos (using AVFoundation) and store it all in Core Data. I discovered, as suspected, that all of this would need to be threaded...otherwise the UI gets extremely sluggish.

I have never attempted to combine Core Data with concurrency before so I read up on it as best I could. I feel like I understand what I'm supposed to do, but for someone reason it's not right. I crash with this error: "Illegal attempt to establish relationship "managedDataPoint" between objects in different contexts. I know what this means, but I thought what I have below would avoid this (I'm following what I've read)...since I get an Object ID reference from the main context, and use that to grab a new reference to the object and pass it to the "temp" context...but that isn't working as Core Data still claims I'm attempting to create a relationship across contexts (where?). Appreciate any help. Thank you!

-(void)snapPhotoForPoint:(ManagedDataPoint*)point
{

if (!_imageCapturer)
{
    _imageCapturer = [[ImageCapturer alloc] init];
}

if (!_tempContext) {
    _tempContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
    _tempContext.parentContext = self.managedObjectContext;
}

__block NSManagedObjectID* pointID = [point objectID];

[_tempContext performBlock:^{

    NSError *error = nil;

    Photo *newPhoto = [NSEntityDescription insertNewObjectForEntityForName:@"Photo" inManagedObjectContext:_tempContext];
    UIImage *image = [_imageCapturer takePhoto];
    newPhoto.photoData = UIImageJPEGRepresentation(image, 0.5);

    ManagedDataPoint *tempPoint = (ManagedDataPoint*)[self.managedObjectContext objectWithID:pointID];
    newPhoto.managedDataPoint = tempPoint; // *** This is where I crash

    if (![_tempContext save:&error]) { // I never get here.
        DLog(@"*** ERROR saving temp context: %@", error.localizedDescription);
    }
}];
}

Upvotes: 0

Views: 87

Answers (1)

Volker
Volker

Reputation: 4658

Shouldn't

ManagedDataPoint *tempPoint = (ManagedDataPoint*)[self.managedObjectContext objectWithID:pointID];

not be

 ManagedDataPoint *tempPoint = (ManagedDataPoint*)[_tempContext objectWithID:pointID];

Otherwise you are working with different contexts! Also you should check if objectID is a temporary ID and acquire a "final" one in case of.

Upvotes: 1

Related Questions