I’m developing an application through Core Data and I need to perform some calculation in a background thread to create an xml file based on specific NSManagedObject.
Following the documentation, I set up NSOperation subclass. This class has a property like the following:
@property (nonatomic, retain) NSArray* objectIDs;
where objectIDs is an array of managed object ids (of type NSManagedObjectID). This is necessary according to the documentation: NSManagedObject are not thread safe.
Inside the main of NSOperation subclass I’m doing the following:
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSManagedObjectContext *exportContext = [[NSManagedObjectContext alloc] init];
[exportContext setPersistentStoreCoordinator:[self persistentStoreCoordinator]];
for (NSManagedObjectID* objectID in self.orderObjectIDs) {
NSError* error = nil;
Order* order = (Order*)[exportContext existingObjectWithID:objectID error:&error];
// order.someRelationship is fault here...
// Create XML file here...
}
[exportContext reset];
[exportContext release], exportContext = nil;
[[NSNotificationCenter defaultCenter] postNotificationName:kRegisterComplete object:self];
[pool drain];
pool = nil;
Inside the for loop I’m fetching the right object using existingObjectWithID:error method of NSManagedObjectContext class since
Unlike objectWithID:, this method never returns a fault.
The method works. I’m able to retrieve the properties of that retrieved object. The only problem is that relationships are fetched as faults.
Said this, I have two questions.
First, is this the right approach to fecth NSManagedObject in a background thread?
Then, how can I fetch relationships for each fetched object within the for loop? Do I have to create a NSFetchedRequest to fetch the relationship object based on the specific object that has been fetched through the id?
Thank you in advance.
Why do you care that the relationship is a fault? Accessing it will fill the fault and return the data, are you concerned about disk I/O for some reason?
You may try using prefetching to alleviate some of the I/O overhead, but it’s utility is limited to the relationship on the entity being fetched:
https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/CoreDataFramework/Classes/NSFetchRequest_Class/NSFetchRequest.html
In that case you would create a fetch request with a predicate like so:
That will return to you only the managed object you desire, and with relationship pre-fetching the relationship won’t be a fault.
You could further optimize this by using a IN clause and fetching all the objects at once: