Question

I’m doing the iOS side of a sync routine, and I’m trying to keep a low memory profile.

The mom has these 2 entities:

  • NSManagedObject Bar
    • to-many relationship to NSManagedObject Foo (“fooMembers”)
  • NSManagedObject Foo
    • to-one relationship to NSManagedObject Bar
    • NSString attribute “masterObjectID”
    • many other relationships and attrs

I need to assemble a collection of all masterObjectID strings held by all the fooMembers of some bars that have been fetched. To do this, I iterate through the bars’ fooMembers -- which I assume fires the faults of all the foos -- and extract the masterObjectIDs, adding them to my collection.

The masterObjectID strings don’t take up too much memory, but the foos do.

So my solution is to surround the foo-fault-firing iteration with an autorelease pool, retaining the masterObjectID strings but hoping that the foos will be released from memory when I drain that pool:

    NSMutableSet *smsetExistingMemberIDs = [NSMutableSet setWithCapacity:[bar.fooMembers count]];

    NSAutoreleasePool *subpool = [[NSAutoreleasePool alloc] init]; // POOL

    for (Foo *foo in bar.fooMembers) 
        [smsetExistingMemberIDs addObject:[foo.masterObjectID retain]]; // retain the string so that it will survive the drain

    [subpool drain]; // DRAIN

    // work with smsetExistingMemberIDs... 

But am I right? Does firing a fault actually put an NSManagedObject into the current autorelease pool? Or is my pool declaration and draining for naught?

Was it helpful?

Solution

Wienke,

The easiest answer is to create a separate managed object context (MOC) inside your autorelease pool. That way, when you are done with the loop, you can purge all of the items at one time. With a separate MOC, you will need to listen for changes but that is rather straightforward. Apple has a few examples that show private MOCs just for these kinds of actions.

Andrew

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top