14

I'm still not that great with memory management techniques, and wondered if someone could explain this weird behaviour to me. Consider these 3 pieces of code which I have been testing:

DofView* dofView = [[DofView alloc] initWithNibName:@"DofView" bundle:nil];
NSLog(@"dof retain count = %d", [dofView retainCount]); 

This logs: retain count = 1. This is fine.

DofView* dofView = [[DofView alloc] initWithNibName:@"DofView" bundle:nil];
[dofView release];
NSLog(@"dof retain count = %d", [dofView retainCount]); 

This logs: retain count = 1. Shouldn't it be 0??

DofView* dofView = [[DofView alloc] initWithNibName:@"DofView" bundle:nil];
[self.navigationController pushViewController:dofView animated:YES];
NSLog(@"dof retian count = %d", [dofView retainCount]);

This logs: retain count = 5. I have NO idea why its five?

Cany anyone shed any light on this at all? Im concerned that I'm eating up memory every time I'm creating a new view.

Thanks!

rich
  • 141
  • 3

7 Answers7

2

Do not rely on retainCount for memory analysis. Go through the reference documents on Memory Management for further info

visakh7
  • 26,280
  • 8
  • 53
  • 69
2

Looking at retain count is strongly discouraged, it won't give you any valuable information. If you want to know if something is getting properly released you should put a breakpoint or a log-entry in the dealloc method of your class - when dealloc is called the object is very soon to be released. Apart from the instruments app, this is what I use to find retain-cycles.

iceydee
  • 969
  • 6
  • 10
1

When to use -retainCount?

retaincount seems to be useless

Community
  • 1
  • 1
Zaky German
  • 13,986
  • 4
  • 22
  • 30
1

It's important to know release happens immediately (autorelease takes a while).

So why does your object still have a retain count of 1?

Because it's been deallocated - it's not your object anymore, it's just some free memory!

Try doing this:

NSObject* o = [[NSObject alloc] init];
NSLog(@"retain count = %d", [o retainCount]); 
[o retain];
NSLog(@"retain count = %d", [o retainCount]); 
[o release];
NSLog(@"retain count = %d", [o retainCount]); 
[o release];
NSLog(@"retain count = %d", [o retainCount]); 

You get the output

retain count = 1
retain count = 2
retain count = 1
retain count = 1

You might expect the last line to say 0, not 1. However, it won't bother decrementing the retain count if it's going to be released - what would be the point!

Actually, the fact that the last line outputs anything at all without crashing is lucky - because the object has been deallocated, there's nothing stopping that memory being used by something else - it's effectively just random data now. This is exactly the kind of bug that causes EXC_BAD_ACCESS crashes :)

In fact, you get a compiler analyser warning on the final NSLog because you're passing a message to an object that doesn't exist any more :)


As for the retain count of 5 - I can only echo the other answers - you don't know what's going on inside objects - just because you only called retain once doesn't mean that no-one else called retain :)

As long as you release for every retain you make, you're doing the right thing.

If you're worried about leaks, use the profiler and check!

deanWombourne
  • 37,003
  • 13
  • 93
  • 99
  • 2
    I would go as far as to say that the last `NSLog` statement is a programming error. You should **never** access an object reference once you have released it. Releasing an object is explicitly stating; *I am done with the object and do not need it anymore*. The last `NSLog` statement can and will cause cause crashes down the road. A good tip is to alway `nil` out any object you release, `[obj release], obj = nil;` is a good and explicit way to do it. – PeyloW May 10 '11 at 13:39
  • @PeyloW - That's exactly my point - the reason there's an unexpected answer is because __it's wrong__! – deanWombourne May 10 '11 at 13:55
  • @deanWormbourne - I only wanted to point out that I think it is important stress that the result may not only be the wrong answer, but a crash. So that code like this is never left in apps, even for debug/test purposes. – PeyloW May 10 '11 at 13:59
  • Yep, I've updated my answer to contain a paragraph warning that it will probably crash :) – deanWombourne May 10 '11 at 14:10
0

The retainCount property depends on how the UINavigationController deals with the controller you are pushing. If it is retained various times inside the UIViewController object you should not be worried. The important thing is that when you use that object, you release it when you do not need it any longer.

E.g. in this case, since you are pushing a new controller to the navigator, you should do this:

DofView* dofView = [[DofView alloc] initWithNibName:@"DofView" bundle:nil];
[self.navigationController pushViewController:dofView animated:YES];
[dofView release];

The retain count for the object is probably not updated instantaneously, so you should not really care about that count.

If you think that you are leaking memory, you should use the profiling tools inside Xcode (search for memory leaks).

Hope this helps.

marzapower
  • 5,385
  • 7
  • 34
  • 70
0

do not rely on retain count. in past i also try to check retain count for memory management but it always confuse me(check this link when retain count confuse me[http://stackoverflow.com/q/5483357/644149] . just follow simple guide line then u will have not memory leaks in ur apps

when u use alloc, new, copy, retain then you should also do release that object. simple

Iqbal Khan
  • 4,416
  • 6
  • 41
  • 78
-1

The release call doesn't take effect immediately, and so the retain count may not look correct. You could use the Leaks tool to track memory issues, but so long as you follow the memory mgmt rules, you should be okay, generally.

Alex Reynolds
  • 91,635
  • 50
  • 223
  • 320
  • 3
    release takes effect immediately. autorelease takes a while to happen. The reason retainCount _looks_ incorrect is because you don't know what happens inside an object/framework. - it might be retained by something else. – deanWombourne May 10 '11 at 11:37