[CoreData] Background Insertion (was Save in Core Data from another thread)
[CoreData] Background Insertion (was Save in Core Data from another thread)
- Subject: [CoreData] Background Insertion (was Save in Core Data from another thread)
- From: "malcom malcom" <email@hidden>
- Date: Tue, 30 Oct 2007 16:39:40 +0100
Looking at this thread
<http://www.cocoabuilder.com/archive/message/cocoa/2007/6/5/184252>
I've used this code in order to perform a background insertion:
This is the method that create a new thread. I've decided to make a
new thread each x messages received (and this should be a problem):
if ([listOfTempArticles count] == MIN_CHUNK_TO_SAVE) {
[NSThread detachNewThreadSelector: @selector(storeArticleDataList:)
toTarget: [[group databaseArchive] persistentStoreArchive]
withObject:listOfTempArticles];
}
This is my thread method:
- (void) storeArticleDataList:(NSMutableArray *) listOfMessages {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[listOfMessages retain];
// MAKE MY MANAGED OBJECT CONTEXT LINKED TO THE SAME PERSISTENT STORE
NSManagedObjectContext *context = [self autoreleaseManagedObjectContext];
// ARCHIVE MY DATA. Inside this method there is a [context
insertObject: newCreatedObject];
int k;
for (k=0;k < [listOfMessages count]; k++)
[self _storeArticleDataInThisArchive: [listOfMessages
objectAtIndex:k] onlyHeader: NO ctx: context];
[listOfMessages removeAllObjects];
// SAVE THIS CONTEXT, COLLECT THE OBJECTID AND PASS IT TO THE MAIN THREAD
NSSet* insertedObjects = [context insertedObjects];
NSError *error = nil;
if ( [context save:&error] ) {
NSSet* insertedIDs = [[insertedObjects valueForKey:@"objectID"] retain];
[self performSelectorOnMainThread:@selector(dataSaved:)
withObject:insertedIDs waitUntilDone:NO];
}
[pool release];
}
This is the method called in main thread. It refresh newly inserted object.
- (void) dataSaved:(NSSet * )list {
NSEnumerator* enumerator = [list objectEnumerator];
NSManagedObjectID* objectid;
while ( (objectid = [enumerator nextObject]) != nil ) {
NSManagedObject* object = [managedObjectContext
objectWithID:objectid];
[managedObjectContext refreshObject:object mergeChanges:NO];
}
[list release];
}
Now the problem is this. If I try to perform a partial save (for
example each 100 messages with a total of 500, so 5 threads) when the
second thread starts the program crash.
Why? My opinion is this: because at each insertion the program search
for the parent of newly inserted message if this parent is not
available (core data is saving it in previous thread) the second
thread cannot found it. I think that the problem is this. Anyone have
a solution? Should I perform a single background save in order to
perform a correct operation? What's the standard way?
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden