简体   繁体   中英

Saving Context At a Later Stage - Saving Pointer To Context ? Core Data

I have the following code which inserts a new entity into a Core Data model (via Magical Record) :

- (void)insertWithData:(NSDictionary *)dataDictionary {

DLog(@"Inserting %@", [_entityClass description]);

NSManagedObjectContext *context = [NSManagedObjectContext contextForCurrentThread];

id entity = [_entityClass createInContext:context];

[entity setValuesFromDictionary:dataDictionary];

if ([entity isKindOfClass:[Syncable class]]) {
    [entity setValue:YesNumber forKey:@"syncedToServer"];
}

[context save];
}

As this code runs multiple times in a FOR loop called from another class, I would like to only save the context once the loop has completed to optimise performance.

My question is what is the best way to do this ? Should I save a reference to the context here (eg in the app delegate) and then save using this reference in the calling class ? Or can I just call NSManagedObjectContext contextForCurrent Thread again in the calling class and use this reference - ie in the calling class :

NSManagedObjectContext * context = [NSManagedObjectContext contextForCurrentThread];
[context save];

You can do this in the following way:

[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext){
    // your for loop
}];

Please read http://saulmora.com/2013/09/15/why-contextforcurrentthread-doesn-t-work-in-magicalrecord/ for more information about why you shouldn't use contextForCurrentThread.

If you'd like to save at the end of the loop, I suggest passing in your NSManagedObjectContext as a parameter:

- (void) insertData:(id)data inContext:(NSManagedObjectContext *)context;
{
   //do all your data stuff here.

}

And you'd use it like so:

NSManagedObjectContext *context = [NSManagedObjectContext MR_confinementContext];
for (id obj in objCollection)
{
   [self insertData:obj inContext:context];
}
[context MR_save];

Yes, you can save context after loop. It's much better than save in each iteration. If you'll take a look into MagicalRecord src, you'll see that MR_contextForCurrentThread returns always same context for same threads, if there's no context for thread MagicalRecord creates it.
Also, you don't need to pass context [_entityClass createInContext:context] , just [_entityClass MR_createEntity] - it will be created on current thread's context

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM