I'm using CloudKit to download an array of records (contained in myArray) The myArray enumeration is within the completion handler of the CloudKit block. There are a few nested CloudKit queries and array enumerations (example below). From there, I'm creating managed objects in a loop, and saving them, which will run only on first launch and then I'd expect Core Data to have them available persistently, so the app is designed to retrieve them without the need of re-creating them.
The problem is that my objects do not appear to save, as on the apps second launch the views are empty (or that the app saves some, or it crashes), and will only fill if I re-run the code to create the objects.
I think the issue may to do with concurrency issues / threads + Core Data - which seems to be the case after adding the compiler flag suggested. Consequently, I edited my code to make use of private queues for the NSManagedObjectContext, but still have crashes. I've edited the example below to show what my code looks like now.
I've simplified the code below for clarify and the purpose of the example, but it is more or less what I have:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//Download records from CloudKit, the following enumeration is within the CloudKit completion handler
[myArray enumerateObjectsUsingBlock:^(NSDictionary * obj, NSUInteger idx, BOOL * stop) {
MyManagedObj *managedObjToInsert = [NSEntityDescription
insertNewObjectForEntityForName:@"entityName"
inManagedObjectContext:self.managedObjectContext];
managedObjToInsert.property = obj[@"property"];
//Get some new records from CloudKit with predicate based on this object which is related to the new records, this next block enumeration is in the completion handler of the new query
[myNextArray enumerateObjectsUsingBlock:^(NSDictionary * obj, NSUInteger idx, BOOL * stop) {
MyManagedObj *nextManagedObjToInsert = [NSEntityDescription
insertNewObjectForEntityForName:@"entityName"
inManagedObjectContext:self.managedObjectContext];
nextManagedObjToInsert.property = obj[@"property"];
nextManagedObjToInsert.relatedObj = managedObjToInsert; //relational
}];
}];
NSError *error;
if (![self.managedObjectContext save:&error])
{
NSLog(@"Problem saving: %@", [error localizedDescription]);
}
}
I've added the flag suggested in the answers below, and it seems like my managedobjectcontext is being passed outside the main thread, giving unpredictable results. Where do or how do I use the private queue blocks - assuming that is the solution to the problem?