views:

59

answers:

3

I'm using CoreData (with SQLite as the store) in an iOS 4 iPhone application to store data that i initially retrieve from an xml file. My data model contains more than 15 entities and I am concerned about memory consumption since I saw CoreData creating all the NSManagedObject in memory to represent the object graph of my data model. I parse the xml file with a SAX libxml2 based parser and try to store each 'agglomerate set' of entities together chunk by chunk, but i'd like to release each managedobject after this agglomerate has been inserted and the managed context saved, in order to save memory for the next agglomerate. I saw that i have to use refreshObject: mergeChanges: to counterbalance the multiple retain each object has received while associated to others by relationships (as designed in the data model). I do that after saving the context, but next when I try to look up again in the store trying to fetch what I inserted before it returns nothing. Am I missing something?

A: 

I think you have to do this for every change

NSManagedObjectContext *moc;
NSError *error;
[moc save:&error];

Otherwise it will be discarded

Jongsma
I am doing it indeed. After that i call refreshObject: mergeChanges: and try to release the nsmanaged objects. Later I try to fetch from the context but nothing seems to be stored
rano
A: 

If all you do is importing (e.g. you don't need to keep the inserted objects to display to the user and so on), you can simply use [moc reset] after the save. So the algorithm would look something like this:

NSManagedObjectContext* moc = ...;
while ([xmlData hasMoreObjects]) {
    // Create e.g. 500 objects and insert them into the managed object context
    NSError* error = nil;
    if (![moc save:&error]) {
        // handle the error
    }
    [moc reset]; // Here the inserted objects get released in the core data stack
}

Resetting the managed object context does the same as if you would refresh every object (as you did before). Also you should consider using the [[NSManagedObject alloc] initWithEntity:insertIntoManagedObjectContext:] instead of the convenience methods on NSEntityDescription, because you can release them just after you don't need them anymore, and they won't stay in memory until the autorelease pool gets cleared.

Take a look at the Core Data Programming Guide, as it contains a whole section centered around efficiently importing data and one about memory management with Core Data.

frenetisch applaudierend
thanks I will try [moc reset]. Atm I am using NSEntityDescription entityForName:inManagedObjectContext: and then initWithEntity:insertIntoManagedObjectContextto create a NSManagedObject but it seems i cannot fully release it (after the initWithEntity it has a retain counter of 2)
rano
I guess it is not 1 since they are inserted into the context which is retaining them (even if I set setRetainsRegisteredObjects:NO).
rano
You should not rely on the retain count, this is a very inaccurate way of determining if you're leaking an object. If you do a reset, core data will let go of your data (mostly, there is still some data in the row cache, etc.). Try to find leaks using Instruments. It is a great tool to see where your memory goes away, and where to optimize.
frenetisch applaudierend
A: 

You can't directly/manually manage the memory of managed objects because the context has control the lifecycle of the objects to maintain graph integrity.

If you can process the import in discrete chunks, save the context after each chunk followed by:

[context refreshObject:theObject mergeChanges:NO]

... which will convert the newly saved objects into faults so they take up very little memory.

You only need faults to set relationships with so the objects processed in the previous chunk will still be available to set in relationships in the current chunk.

Whenever possible, I create objects in one pass, save them, convert them to faults and then set relationships in the next pass. This is not always practical if you have a required relationships.

You might want to check out the Core Data Programming Guide:Efficiently Importing Data if you haven't already done so.

TechZen