Steven Elliott
Steven Elliott

Reputation: 3224

Core Data Memory Leak - iPhone iOS4

I desperately need help with a memory leak in my iPhone app. The app is ready to submit to the app store, is stable, has no memory leaks at all in iPhone simulator or Clang ... but seems riddled with them on my iPod Touch.

They all seem to stem from managedObjectModel when I'm trying to retrieve data from Core Data.

The Core Data code in my app was automatically created by Xcode a while back, I've noticed that the code has since changed when you get xcode to generate it ... I've tried with the old and new but it makes no difference.

If I comment out the following code, the problem goes away ... can anyway see what's wrong with it? I've spent 9 hours on this so far and just can't figure it out!

NSString *entityForName = [[NSString alloc] initWithString:@"OfflineSettings"];

NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:entityForName inManagedObjectContext:[self managedObjectContext]];
[request setEntity:entity]; 

[entityForName release];

NSSortDescriptor *sortById = [[NSSortDescriptor alloc] initWithKey:@"Id" ascending:YES];
[request setSortDescriptors:[NSArray arrayWithObject:sortById]];
[sortById release]; 

NSError *error;
NSMutableArray *mutableFetchResults = [[[self managedObjectContext] executeFetchRequest:request error:&error] mutableCopy];
if (mutableFetchResults == nil) {
    // Handle the error.
    NSLog(@"Error fetching");
}

int intId = -1;

if ([mutableFetchResults count] == 0) {
    TTDERROR(@"No id has been saved to offline settings");      
} else {    
    OfflineSettings *offlineSettings = (OfflineSettings *)[mutableFetchResults objectAtIndex:0];        
    intId = [offlineSettings.Id intValue];
}

[mutableFetchResults release];
[request release];

The leak specifically seems to be on this line:

NSMutableArray *mutableFetchResults = [[[self managedObjectContext] executeFetchRequest:request error:&error] mutableCopy];

.. and the code for [self managedObjectContext] is as follows in case it helps ..

- (NSManagedObjectContext *)managedObjectContext {

    if (managedObjectContext_ != nil) {
        return managedObjectContext_;
    }

    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (coordinator != nil) {
        managedObjectContext_ = [[NSManagedObjectContext alloc] init];
        [managedObjectContext_ setPersistentStoreCoordinator:coordinator];
    }
    return managedObjectContext_;
}

I'm really at a loss, so I would be so grateful for some help!

Steven

Upvotes: 2

Views: 1543

Answers (1)

TechZen
TechZen

Reputation: 64428

You don't need the mutable copy. executeFetchRequest: returns an autoreleased static array and you're not mutating the array. (I keep seeing this. Must be in an example somewhere.) Likewise, creating the entityForName NSString is pointless. Just put the string literal in the entityForName: to eliminate another possible source of error.

Niether of these are the likely source of the leak but you should remove them anyway.

As a rule of thumb, if you have troubles on device but not simulator or on one hardware but not others, then the problem is in a library/framework that is not properly compiled for the hardware where the error occurs. There really isn't any type of coder error that leaks in one environment but not others. When we make a mistake, it's universal.

It's also possible for resources such as images and sounds to behave differently because different devices use different graphics and audio hardware. That, however, is rather rare.

If you run the code through Instruments it should tell you exactly what object is leaking.

Upvotes: 1

Related Questions