views:

245

answers:

3

Hi there,

I have managed to get myself confused about some elements of memory management. I am new to objective-c, and memory managed languages generally.

I have read the memory management guidelines, but I remain confused about a couple of things. 1) Is there any need to clean up ivars, and method variables that are not retained by any object. For instance

-(void) someMethod{
int count = 100;
 for (int i=0; i <count;  i++) {
  NSLog(@"Count = %d", i);
 }
    }    

What happens to the "count" var after the method is complete? If a method allocates lots of temporary variables, do those get removed from memory as long as they are not unreleased, alloc'd objects? Or do i need to set them to nil in some way?

2) If i have a static variable, for instance an NSString, do I have to do anything for that to be removed from memory when the class is dealloced?

3) I have noticed that NSStrings seem to have a retainCount of 2147483647 which wikipedia tells me is the max value for a 32 bit signed integer.

http://en.wikipedia.org/wiki/2147483647

myString retainCount = 2147483647

-(void) someMethod{
NSString *myString = @"testString";
NSLog(@"myString retainCount = %d", [myString retainCount]);
// logs:  myString retainCount = 2147483647
}

What happens to this at the end of the method? Does this memory ever get emptied? The string is not being referenced by anything. My understanding is that the @"" convenience method for NSString returns an autoreleased object, but whats the point of autoreleasing something with a retainCount of 2147483647 anyway? In that case, whats the point of retaining or releasing ANY NSString?

I am well aware that retainCount should be ignored, but it just bugs me not to know what's going on here.

4) Does this matter at all? I know that the memory associated with an NSString isn't much to write home about, but I want to be a good memory management citizen, and I'm more interested in best practices than anything else.

+3  A: 

Retain/release only matters for objects, not int, bool, float, double or other built-ins. So use it for id or other classes that you hold a pointer to an object. In your example, count doesn't need to be retained or released. It is allocated on the stack which is automatically cleaned up when the function returns.

You do need to deal with any local objects you alloc. Those are created with a retainCount set to 1, so you need to either hold on to them for later or release them. Most Cocoa functions (that don't start with copy or alloc) return an object that is autoreleased. This means that they will have release called on them later -- you can only hold these after the function if you call retain on them. If you want them to be cleaned up, you don't need to do anything (calling release would result in too many release calls).

If you have a static variable pointing to an object, then it is not touched when objects of that class are dealloced. If you want it to be released, you have to call release on it. If the static is an int, bool, or other built-in, you don't (can't) call release on it. That's part of the global memory of your app.

NSStrings that are set to string literals should not have release called on them. The retainCount is meaningless for them. That value is also -1 for signed int values.

If you do this -- [[NSString alloc] initCallHere:etc] -- you have to call release on it. Most of the time you get strings, you don't use alloc, so you don't need to call release. If you retain one, you need to call release.

Yes, it does matter. Over time leaks will cause the iPhone to kill your app.

Lou Franco
Thanks for your answer, so will strings created using @"" syntax stay in memory until the application is killed? Or are they put into a pool for cleanup unless retained further?
AVeryDev
`@""` strings are effectively static -- which is to say, part of the memory image of your application. You do not need to clean them up (although it shouldn't actually matter if you do, since they have, for practical purposes, an infinite retain count). If you `alloc`, `copy` or `new` an object using such a string, however, you should definitely `release` that object.
walkytalky
Could the number of @"" strings in your application, for instance lots of log statements, or other usage of @"" for short term needs effect the performance of an application or significantly increase its memory footprint generally and negatively?Should short term use string variables, created using @"" be set to nil when their usefulness has expired?
AVeryDev
Let's say you had 5,000 log messages of 100 characters each. I think @"" are wide, so 2 bytes per character. That's 5k X 100 x 2 == ~1mb. Probably you have a lot less than that. I wouldn't worry about it.
Lou Franco
+1  A: 
  1. You don't need to worry about count cause it's an integer, a primitive data type, not an object.

  2. I've read that those just go away upon app termination or if you explicitly release them.

  3. You are right in that you should not worry about the retain count in that way. Cocoa automatically gives @"" (NSConstantString objects) the absolute highest retain value so that they cannot be de-allocated.

  4. You are over complicating the subject. The point of the three guidelines is so that you know that you only have to worry about memory management in three specific situations. Apple gives you these guidelines so that one doesn't have to worry about the specific internals for every single class (like manually tracking retainCount), not to mention that sometimes Cocoa does things differently (as with NSConstantString). As long as you remember these guidelines, you really don't have to know the very gritty details of what's going on underneath (of course, an understanding of the retain count concept helps, but compare this to manually tracking it).

I don't know which guide you read specifically, but if you haven't given this one a try, I highly recommend it. It summarizes the three guidelines in a concise and direct manner.

Jorge Israel Peña
+2  A: 

The Cocoa memory management rules only cover Objective C objects.

Local variables (non-static) are cleaned up when any subroutine or method exits (actually the stack memory is just reused/overwritten by subsequent subroutines or methods in the same thread). Constants which require memory (strings) and static variables are cleaned up when the app is torn down by the OS after it exits. Manually malloc'd memory is cleaned up when you manually free it.

But any object you alloc or retain: (whether assigned to an ivar, local, global, static, etc.) has to managed like any other object. Be careful assigning objects to global variables, unless you are really good at retain count management.

hotpaw2