Padin215
Padin215

Reputation: 7484

Update a Core Data entity in another context

I have a NSManagedObject Person Scott fetched from NSManagedObjectContext context1. I also have the same Scott fetched from NSManagedObjectContext context2.

I know if I fetch them from the same context, that if one is updated, the other will also be updated, but my current structure would not easily allow me to pass the same context around. I'm wondering if there is another way, something along the lines to KVO.

Can I update the Person Scott in context2 when I make a change to the Person Scott in context1?

EDIT:

Tried testing:

NSError *error = nil;

NSManagedObjectContext *context = [NSManagedObjectContext MR_context];
NSManagedObjectContext *context2 = [NSManagedObjectContext MR_context];

Boundary *boundary1 = [Boundary MR_findFirstInContext:context];
DLog(@"boundary1.name: %@", boundary1.name);
DLog(@"boundary1.managedObjectContext: %@", boundary1.managedObjectContext);

Boundary *boundary2 = (Boundary *)[context2 existingObjectWithID:boundary1.objectID error:&error];
DLog(@"boundary2.name: %@", boundary2.name);
DLog(@"boundary2.managedObjectContext: %@", boundary2.managedObjectContext);

boundary1.name = @"new name";

// Added this, does not change results
[context2 MR_observeContext:context];

DLog(@"boundary1.name: %@", boundary1.name);
DLog(@"boundary1.managedObjectContext: %@", boundary1.managedObjectContext);

DLog(@"boundary2.name: %@", boundary2.name);
DLog(@"boundary2.managedObjectContext: %@", boundary2.managedObjectContext);

results:

DEBUG | -[LoginViewController viewDidLoad] | boundary1.name: 997677
DEBUG | -[LoginViewController viewDidLoad] | boundary1.managedObjectContext: <NSManagedObjectContext: 0x1cdc6b20>
DEBUG | -[LoginViewController viewDidLoad] | boundary2.name: 997677
DEBUG | -[LoginViewController viewDidLoad] | boundary2.managedObjectContext: <NSManagedObjectContext: 0x1cdd7930>
DEBUG | -[LoginViewController viewDidLoad] | boundary1.name: new name
DEBUG | -[LoginViewController viewDidLoad] | boundary1.managedObjectContext: <NSManagedObjectContext: 0x1cdc6b20>
DEBUG | -[LoginViewController viewDidLoad] | boundary2.name: 997677
DEBUG | -[LoginViewController viewDidLoad] | boundary2.managedObjectContext: <NSManagedObjectContext: 0x1cdd7930>

The change to boundary1's name does not persist into boundary2's name.

Upvotes: 0

Views: 2096

Answers (3)

Buju
Buju

Reputation: 1556

you need to save your change in order for other contexts to be notified by the change

[context MR_saveToPersistentStoreAndWait]; or

[boundary1.managedObjectContext MR_saveToPersistentStoreAndWait];

CoreData entity updated notifications will only be posted when you save a context. You can view the context as a scratch book. If you make any change to an entity from context1 and you don't want those changes to be persisted, you can simply discard the context (set context to nil) and nothing will be persisted.

Upvotes: 0

Mike Pollard
Mike Pollard

Reputation: 10195

You need to merge changes from one context to another. Since it looks like you're using MagicalRecord you can do tho easily with:

[context2 MR_observeContext:context1]

Upvotes: 1

Lorenzo B
Lorenzo B

Reputation: 33428

You can pass an object from a context to another through the NSManagedObjectID. As the doc says

A managed object ID uniquely identifies the same managed object both between managed object contexts in a single application, and in multiple applications (as in distributed systems). Identifiers contain the information needed to exactly describe an object in a persistent store (like the primary key in the database), although the detailed information is not exposed.

Based on that, if you pass the object from a context through id, then in the other one you can retrieve, modify and save it. The former context will see those changes.

Within a context you can use, for example, existingObjectWithID:error: to return the object with the specified id.

Please also refer to What's the difference between -existingObjectWithID:error: and –objectWithID:? and Apple doc.

Let me know if you need something else.

Upvotes: 3

Related Questions