0

The leak instruments warn me about a memory leak related to this part of code:

[self.contview addSubview:nav.view];

Here are how I manage the view:

    [nav.view removeFromSuperview];
    self.nav = [[[destinationClass alloc] initWithNibName:pagename bundle:nil] autorelease];
   [self.contview addSubview:nav.view];

Is it normal that the self.nav has a retainCount of 2 just after been allocated?Could this be related to the memory leak?

I'm very new to the memory management can someone give me some help?

Many Thanks

  • Could you post all of the related code? This all looks a bit odd to me, but without context it's hard to tell. – Stefan Fisk Dec 11 '13 at 18:12
  • 3
    www.whentouseretaincount.com -- the `retainCount` is irrelevant. Use the allocations instrument to see the stack trace of each retain/release event. – bbum Dec 11 '13 at 19:21

1 Answers1

2

Assuming nav is a strong (retain) property, it retains the view controller you are assigning here:

self.nav = [[[destinationClass alloc] initWithNibName:pagename bundle:nil] autorelease];

effectively, the retain count after this line of code is 1; +2 for alloc and retain and -1 for autorelease. Generally you should never use retainCount method to determine the actual retain count of the object, maybe this answer will give you more insight why. Every alloc, retain or copy call should be matched with a release or autorelease call. You should add a matching release call in dealloc method of your class

-(void) dealloc {
    [_nav release];
    _nav = nil;
    [super dealloc];
}

Don't use manual memory management, use ARC, it will make your life much easier :)

Community
  • 1
  • 1
Marko Hlebar
  • 1,973
  • 17
  • 18
  • 1
    Of course, the RC's value of 2 doesn't actually reflect the `autorelease` and, thus, it is effectively 1. But only coincidentally in that it might be 42 and still be valid. The absolute retain count is meaningless. Really, it is +1 for alloc, +1 for the `self.nav =` and -1 for the autorelease, yielding a +1 after that line of code is executed (and, thus, requiring a -1 somewhere else to make this code correct). Note that you should probably use `[_nav release];` or `self.nav = nil;` to prevent a dangling pointer. – bbum Dec 11 '13 at 19:23
  • You're right the retain count is effectively 1 after the alloc, retain and autorelease, now that I'm reading my answer again I see what you are trying to point out. I'll do a little rephrasing :) – Marko Hlebar Dec 11 '13 at 19:29
  • That `dealloc` will crash; just use `[_nav release]; _nav = nil;` or `self.nav = nil;`, but don't mix the two. *Generally* the pattern is to release the instance variable directly in `dealloc` and assign directly in `init`. (Good edit, btw! Thanks) – bbum Dec 11 '13 at 20:45
  • but why the leak instruments says that the leak problem is in this line of code :[self.contview addSubview:nav.view]; – user3092283 Dec 11 '13 at 21:06
  • And sorry how can I do the same thing with ARC? just by removing autorelease, am I right? – user3092283 Dec 11 '13 at 21:23
  • @bbum got rusty with my manual memory management. You're right, that would crash, edited again :) – Marko Hlebar Dec 11 '13 at 21:31
  • In my project i'm not using ARC, but if I remove the autorelease: [[destinationClass alloc] initWithNibName:pagename bundle:nil] The leak instruments do not find any leaks... I don't understand the problem. Can you help me? Do you think the problem could be the autorelase and removing it could it lead to some other problem? – user3092283 Dec 12 '13 at 07:40
  • Have you added the release code to dealloc method? Also I see that you are probably calling this method more than once, so when you do [nav.view removeFromSuperview]; do [nav release]; and then do self.nav = [[[VC alloc] init] autorelease]; – Marko Hlebar Dec 12 '13 at 09:22
  • in the dealloc there was already `self.nav = nil;`, if i do `[nav release]` before the alloc the app crash, is not correct remove the autorelease? – user3092283 Dec 12 '13 at 09:40
  • What kind of property is nav? is it retain or assign? – Marko Hlebar Dec 12 '13 at 09:45
  • it s retain `@property (nonatomic, retain) UIViewController` – user3092283 Dec 12 '13 at 09:46
  • Basically, I would do something like this when I would use a method like yours. I would make a method, removeNavView and addNavView. In removeNavView I would do [nav.view removeFromSuperview]; self.nav = nil; in addNavView, I would first call the [self removeNavView]; and then do UIViewController *vc = [[VC alloc] init]; self.nav = vc; [vc release]; – Marko Hlebar Dec 12 '13 at 09:53
  • basically you said to do this: `[self.nav.view removeFromSuperview]; self.nav = nil; UIViewController *vc = [[destinationClass alloc] initWithNibName:pagename bundle:nil] ; self.nav = vc; [vc release]; //[currentappview removeFromSuperview]; [self.contview addSubview:self.nav.view];` Am i right? this again causes the leak intrumenti to raise a leak problem on the same line of code. But if I remove the `vc release` line, again not leak appear, do you think is safe do to this? – user3092283 Dec 12 '13 at 10:09
  • OK, your self.nav.view then has the retain count of 2, because addSubview also increases the retain count. In the dealloc you should also call [self.nav.view removeFromSuperview]; before self.nav = nil; – Marko Hlebar Dec 12 '13 at 10:13
  • I've tried but that did not solve the leak. Do you think is it safe to remove the autorelease from the init? The app seems to not crash and the leak disappear, do you think it could lead to some sideeffects? – user3092283 Dec 12 '13 at 10:21
  • I would have to check the complete code to see what's happening. Removing autorelease is not a solution to the problem, because then you would be leaking the view controller. – Marko Hlebar Dec 12 '13 at 10:27