views:

76

answers:

2

Hello. I'm diving into iOS development and am getting familiar with the tools. At the end of every day, I perform a "Run with instruments tool -> Leaks" on my app to check for any memory leaks I may have implemented that day. It rarely seems to detect any leaks and, while I'd like to think I'm just a natural iOS programmer, I refuse to believe that ;)

Anyhow, I just found what I think is a memory leak in my code and it doesn't get caught by Instruments. I have this line of code...

gkSession = [[GKSession alloc] initWithSessionID:@"testID" displayName:@"Temp Display Name" sessionMode:GKSessionModeClient];

and I found that I wasn't calling release anywhere in my code. My questions are...

  1. Is this a memory leak?
  2. If so, what are some reasons that Instruments might not catch it?

My obvious concern is that I have memory leaks in my code and Instruments isn't catching them.

Thanks so much in advance for your help!

+1  A: 

There are multiple types of dynamically allocated memory.

  1. Memory with a reference count greater than zero which is still referenced and is in use.

  2. Memory with a reference count of zero which is still referenced and is still in use.

  3. Memory with a reference count greater than zero which is not referenced.

  4. Memory with a reference count of zero which is not referenced.

  5. Memory with a reference count greater than zero which is still referenced and is NOT in use.

Type one is normal in use memory. Type two is a bug that will be reported as an illegal access when you try to follow the reference. Type 3 is the type of leak that instruments detects. Type 4 should be freed by the memory system.

Type 5 is a leak which cannot be detected by instruments, and will also not be handled by a full garbage collector. This is what you seem to have.

EDIT:

I forgot type 6 -- Memory with a reference count that doesn't match the number of actual references. This will probably eventually turn into type 2 or 4.

Darron
thanks, darron! do you have any methods for finding type 5 leaks?
BeachRunnerJoe
There are lots of tools to help find these in the Java world, but I'm not familiar with any in iOS. That doesn't mean that they don't exist, I'm not as familiar with the tools there.
Darron
+1  A: 

The answer to #1 is "maybe"... if your view controller gets popped off the stack, and no one else has retained it, then your view controller should get deallocated. But, (and this may be the answer to your question #2) one of the mistakes I made originally was not understanding that when you call pushViewController: the navigation controller will retain your view controller, so you don't have to. Make sure you are releasing your view controller after you create it and push it on the stack.

MyViewController * viewController = [[MyViewController alloc] init...];
[self.navigationController pushViewController:viewController];
[viewController release];

I believe the static analyzer will warn you if you forget the release call in this situation... which is one reason the static analyzer is so great.

If you don't release the view controller at this point, your retain count will always be +1 higher than it should.

I've noticed the static analyzer is MUCH more useful for these things than the instruments' leak tool. (Which, for example, won't find a "leak" that includes circular references... two leaked objects that reference themselves don't show up because "a reference" is still around for your object).

So currently you have something along the lines of...

@interface MyClass : UIViewController
{
     GKSession * gkSession;
}

...

@end

in your implementation you should make sure you release your iVar in your dealloc method:

@implementation MyClass

...

- (void)dealloc
{
     [super dealloc];

     if (gkSession) [gkSession release];
}
@end
Steve
thanks, steve, i seem to be following all the conventions you specified above, so i'm not sure what else to try.
BeachRunnerJoe
does the dealloc for your view controller get called when you pop the view off the stack?
Steve
yeah, it does. it's strange.
BeachRunnerJoe