Reputation: 335
I am running Instruments to find the memoryleaks in my iPhone app.
As you can see on the screenshot below, I get some weird memory leaks, from some Foundation objects.
The ones that bother me the most are the one that should be released "automatically" if I understood right. Such as: NSPredicate predicateWithFormat, NSKeyedUnarchiver unarchiveObjectWithData, and so...
Here a screenshot with more info for the NSPredicate one:
Can you please help me to understand what ma I doing wrong?
In the code I am simply doing that:
NSPredicate *basePredicate = [NSPredicate predicateWithFormat:@"ANY fcLists IN %@", listsIds];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Item" inManagedObjectContext:self.context];
[self.fetchRequest setEntity:entity];
// Load the list of new items
NSPredicate *addedPredicate = [NSPredicate predicateWithFormat:@"fcStatus = -2"];
NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:basePredicate, addedPredicate, nil]];
[self.fetchRequest setFetchLimit:self.nbOfNewItems];
[self.fetchRequest setPredicate:predicate];
tmp = [self.context executeFetchRequest:self.fetchRequest error:&error];
so I shouldn't have to release predicate right? Anyway I tried and it makes my code to crash...
Thank you in advance for your help!
Upvotes: 0
Views: 1229
Reputation: 44886
The retain/release model is not like (for instance) malloc/free. It isn't enough to balance your object creation with a release, or to use a method that returns an autoreleased objects. Every retain
on an object must be balanced with a release
. If you miss just one, the object is leaked. Instruments points out where the object was created, but not where it was leaked. Instruments points out each retain, but does not (and can not) point out which retain is not properly balanced.
You didn't specify what was actually leaking, so I'll have to give a generic example based on your code.
Let's assume basePredicate
was leaking:
basePredicate
(i.e. it calls retain
). That object isn't releasing it.basePredicate
, as above, but that object does release it. It's possible that object hands basePredicate
off to some other object that claims ownership of it by retaining it.If this sounds horrible, it kind of is. But the fix is actually simple: Make sure every time your code claims ownership of an object with retain
(or assignment to a property with retain), it has a corresponding yield of ownership, in the form of a release
or autorelease
(or assignment of nil to the property).
In the past, when I've had a leak I just can't find, I've found the best thing to do is study which objects leak and identify what (if any) relationship they have. Then I go through my code and look for objects I haven't released.
Also, if you haven't yet, start using the static analyzer. It can't find all problems like this, but when it does find one you'll save a lot of time.
Upvotes: 1