D
D
deleted-mezhevikin2014-01-07 19:59:13
Objective-C
deleted-mezhevikin, 2014-01-07 19:59:13

Working with NSManagedObject in different threads using MagicalRecords?

I create an Artist entity in the main thread, then I do some calculations in the background thread, create an Album entity, and link it to the Artist entity.
How to do it right?

- (IBAction)add:(id)sender
{
    Artist *artist = [Artist MR_createEntity];
    artist.title = @"Eminem";

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),^{
        // here a large calculation
        Album *album = [Album MR_createEntity];
        album.title = @"Album 1";
        [artist setAlbums:[NSSet setWithArray:@[album]]];

        dispatch_async(dispatch_get_main_queue(),^{
            [artist.managedObjectContext MR_saveToPersistentStoreAndWait];
        });
    });
}

MagicalRecordTest[2008:1803] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Illegal attempt to establish a relationship 'albums' between objects in different contexts (source = <Artist: 0x15eaa2d0>

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
An, 2014-01-07
@Flanker_4

MR has a set of methods specifically for this.

/* For all background saving operations. These calls will be sent to a different thread/queue.
 */
+ (void) saveWithBlock:(void(^)(NSManagedObjectContext *localContext))block;
+ (void) saveWithBlock:(void(^)(NSManagedObjectContext *localContext))block completion:(MRSaveCompletionHandler)completion;

/* For saving on the current thread as the caller, only with a seperate context. Useful when you're managing your own threads/queues and need a serial call to create or change data
 */
+ (void) saveWithBlockAndWait:(void(^)(NSManagedObjectContext *localContext))block;

/*
 If you want to reuse the context on the current thread, use these methods.
 */
+ (void) saveUsingCurrentThreadContextWithBlock:(void (^)(NSManagedObjectContext *localContext))block completion:(MRSaveCompletionHandler)completion;
+ (void) saveUsingCurrentThreadContextWithBlockAndWait:(void (^)(NSManagedObjectContext *localContext))block;

Those. what you want to do:
//пишу по памяти, могу где-то ошибиться
[MagicRecord saveWithBlock:^(NSManagedObjectContext *localContext){
    Artist *artist = [Artist createInContext: localContext];
    artist.title = @"Eminem";

       Album *album = [Album createInContext: localContext];
        album.title = @"Album 1";

        [artist addAlbumObject:album]; //этот метод, или подобный ему должен автоматически сгенерироваться если Вы правильно генерируете классы Artist|album
}];

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question