0

I have tried to use the Analyze instrument to see the memory leaks, and Xcode gives me a memory leak in this point:

.h

@property (strong, nonatomic) NSManagedObjectContext *managedObjectContext;

.m

@synthesize managedObjectContext = __managedObjectContext;

then in the code I do this:

AppDelegate *appController = [[UIApplication sharedApplication] delegate];

self.managedObjectContext = [[NSManagedObjectContext alloc] init];
[self.managedObjectContext setUndoManager:nil];
[self.managedObjectContext setPersistentStoreCoordinator: [appController persistentStoreCoordinator]];

and in the dealloc this:

- (void)dealloc
{    
    [__managedObjectContext release];
    [super dealloc];
}

It gives me a memory leak on this line:

[self.managedObjectContext setUndoManager:nil];

for this object:

self.managedObjectContext = [[NSManagedObjectContext alloc] init];

I have released it in the dealloc, why a memory leak there?

Lorenzo B
  • 33,216
  • 24
  • 116
  • 190
Piero
  • 9,173
  • 18
  • 90
  • 160

2 Answers2

2

Your _managedObjectContext leaks because its retain count is increased twice, but you only release it once. You have made your property strong which means it will retain the object when it is assigned to it. But you also allocate managedObjectContext without autoreleasing (or manually releasing) it. Hence the error is in this line:

self.managedObjectContext = [[NSManagedObjectContext alloc] init];

The object you allocate will have a retain count of 1, but the synthesized property will retain it one more time, hence giving it a retain count of 2. When you release it in dealloc, it will stay around since it still has a retain count of 1.

What you need to do is either autorelease the object you allocate:

self.managedObjectContext = [[[NSManagedObjectContext alloc] init] autorelease];

or not call the synthesized setter, but assign directly to _managedObjectContext:

_managedObjectContext = [[NSManagedObjectContext alloc] init];

I would recommend the former since the latter will leak if _managedObjectContext is not nil. However if you're sure _managedObjectContext is nil before the assignment, you can pick either one you want.

  • thanks for your answer, so i have to do self.managedObjectContext = [[[NSManagedObjectContext alloc] init] autorelease]; and in the dealloc i delete [__managedObjectContext release]; ? – Piero Jun 03 '12 at 12:45
  • @Piero Yes. The release has to be called in *dealloc* anyway. If you put *strong* (the same as *retain* in your code) you also need to release it when the object is destroyed. On the contrary, you have a memory leak. – Lorenzo B Jun 03 '12 at 14:32
  • ok so i have to edit only this: self.managedObjectContext = [[[NSManagedObjectContext alloc] init] autorelease]; right? – Piero Jun 03 '12 at 15:13
  • if i do in this way, give me a bad_exc_access in the dealloc...on this line [__managedObjectContext release]; how i can do? – Piero Jun 03 '12 at 16:43
  • @Piero Are you sure you don't nullify the value before in your code? In other words, are you sure that you don't call `self. managedObjectContext = nil`? Try also to enable zombies and see what it happens (search enable zombies in Xcode). – Lorenzo B Jun 03 '12 at 17:35
1

This line...

self.managedObjectContext = [[NSManagedObjectContext alloc] init];

...increases the retain count by two, one for the alloc and one for the "strong" on the property.

Try:

__managedObjectContext = [[NSManagedObjectContext alloc] init];
Phillip Mills
  • 30,888
  • 4
  • 42
  • 57
  • ok, but i don't have the arc, i can use retain nonatomic instead of strong?...and then i have still to do this? self.managedObjectContext = [[NSManagedObjectContext alloc] init]; or i can delete that line? – Piero Jun 03 '12 at 12:29
  • I suggest changing the one line, as suggested, and then you will see whether or not your leak goes away. – Phillip Mills Jun 03 '12 at 13:18