Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Need some clarifications on refreshObject:mergeChanges:YES

Some background:

I am trying to store a large amount of data in local DB and I want to do it as efficiently as possible.

Scenario:

There are many entities which are inter-related, such as address is associated with a contact like this:

address <<-> contact

To manage relationships, I have written a method in each subclass of NSManagedObject, below is some code snippet:

// class Contact
- (void)manageRelationships
{
    @autoreleasepool {
        LocalDBManager *localDBManager = [[LocalDBManager alloc] init];

        // managing relationships

        // map associated addresses

        NSPredicate *addressIdPredicate = [NSPredicate predicateWithFormat:@"%K == %@",ADDRESSID,self.addressid];

        // below method returns an object as fault by firing a fetch request against context
         NSSet *retrievedAddresses = [localDBManager retrieveManagedObjectsForEntity:ADDR_ENTITY withPredicate:addressIdPredicate asFault:YES withPropertyValues:NO error:nil];
        self.addresses = retrievedAddresses;


        // managing few more relationships         
    }

}

Point to consider:

Since there can be multiple relationships for an object, I know that memory consumption will increase when I will be mapping relationships.

Question:

I want to turn back an object into fault, without loosing any changes made, once the relationships are mapped.

From apple documentation and some googling I came to know that I can use refreshObject:mergeChanges: method. So I am planning to add below line at end of code block in manageRelationships method:

[[self managedObjectContext] refreshObject:self mergeChanges:YES];

I am a bit confused and want to know that -

Does it mean that whatever changes were made to the object will be stored in persistent store and then the object will turn to a fault? If yes, then can I consider it equivalent to save method of NSManagedObjectContext

Please suggest.

like image 543
Devarshi Avatar asked Feb 14 '13 05:02

Devarshi


1 Answers

First of all you do not need to manage relationships by yourself. Let CoreData handle that.

Core Data automatically resolves (fires) the fault when you access data in the fault. This lazy loading of the related objects is much better for memory use, and much faster for fetching objects related to rarely used (or very large) objects. CoreData performance

You might do this by simple instantiating one-to-many relationship between contact-address.

Regarding to refreshObject:mergeChanges: you are wrong. It is not an equivalent to save: method. If you set merge changes to YES it only means that:

If flag is YES, then object’s property values are reloaded from the values from the store or the last cached state then any changes that were made (in the local context) are re-applied over those (now newly updated) values. Cocoa touch Doc

So if you did some changes in managed object A and then did [context refreshObject:A mergeChanges:YES] than object A would still remain in an unsaved state.

like image 84
Mark Kryzhanouski Avatar answered Jan 03 '23 10:01

Mark Kryzhanouski