开发者

High memory usage during CoreData import

I'm attempting to perform a fairly large CoreData import (around 25,000 rows) while still maintaining a fairly low memory footprint. I've read the documentation surrounding efficient importing of data and have endeavoured to implement everything suggested there (including setting things like my MOC's undoManager to nil).

Unfortunately, my applications memory usage still climbs to around 180MB when running the below code. Upon completion the application will sit at around the 180MB mark, regardless of the final NSAutoreleasePool drain call.

Running the application through Allocations shows that 95% of the memory usage is attributable to my [self.moc save:&error] call. What am I doing wrong here?

- (void)generateCache
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    NSUInteger count = 0, batchSize = 1000;

    // SNIP SNIP

    // Iterate over our directory structure
    for(NSString *item in directoryStructure)
    {
        NSDictionary *info = [fm attributesOfItemAtPath:item error:nil];

        FileRecord *record = (FileRecord *)[NSEntityDescription insertNewObjectForEntityForName:@"FileRecord" inManagedObjectContext:self.moc];
        record.size = [NSNumber numberWithUnsignedLongLong:[info fileSize]];
        record.path = item;

        count ++;
        if(count == batchSize)
        {
            NSError *error = nil;

            if([self.moc save:&error])
            {
                NSLog(@"MOC saved down and reset");
                [self.moc reset];
                [pool drain];

                pool = [[NSAutoreleasePool alloc] init];
                count = 0;
            }
        }
    }

    // Perform any necessary last minute MOC saves
    if (count != 0) {
        [self.moc save:nil];
        [self.moc reset];
    }
开发者_开发百科
    // Drain our NSAutoreleasePool
    [pool drain];

    // Tell our main thread that we're done
    if ([self respondsToSelector:@selector(completedCache)]) 
    {
        [self performSelectorOnMainThread:@selector(completedCache) withObject:nil waitUntilDone:NO];
    }
}


Instead of dealing with auto-release pools, why not explicitly manage the life-cycle of your managed objects by creating them with NSManagedObject's initWithEntity:insertIntoManagedObjectContext:? You can safely release them after modifying the object's properties since a managed object context retains a newly inserted object -- till its saved to the persistent store.

Also, I should mention a couple of problems that I see with your code:

  1. As someone mentioned above, you are not logging errors from the save: operation. You really should -- that may highlight some (possibly unrelated) problem.

  2. If save: is successful, you really should not need to call reset. See this section in the core data guide.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜