views:

123

answers:

5

One thing I'm concerned about is I create two ints, but don't release them. Would it be better to make them NSIntegers?

-(void) flipCoin {

    int heads = [headsLabel.text intValue];
    int tails = [tailsLabel.text intValue];

    if (random() %2 ==1 )
    {
        heads++;
    }
    else {
        tails++;
    }

    headsLabel.text = [NSString stringWithFormat:@"%d", heads] ;
    tailsLabel.text = [NSString stringWithFormat:@"%d", tails];

}
+3  A: 

Local variable are allocated in stack. Don't worry about any leak in code like this.

sha
+2  A: 

No. Your heads and tails variables are local and stored on the stack. This won't cause a leak. Your two NSString assignments near the bottom are created using convenience constructors and will be autoreleased for you.

Greg Sexton
+2  A: 

All default datatypes (int, char, BOOL, etc) are automatically managed for you, and do not (and cannot) be released (for all intents and purposes). NSIntegers behave likewise, as they are just signed ints (or signed longs on 64-bit machines).

Objects you initialize, however, like NSString or NSArray will usually have to be released (unless they are autoreleased, like the NSStrings at the bottom of your code). If you ever call -alloc and -init on something, you will have to later release it. If you ever doubt whether a method returns an autoreleased object, just read the documentation (it will tell you).

Also, if you want to read up on memory management, there are plenty of wonderful sources that will teach you (Google is a great place to start!), and if you ever think that your code leaks memory, run it through Instruments, and you'll be able to tell...

itaiferber
+6  A: 

As sha notes, local variables get allocated in the current stack frame. As soon as the current function call returns, the stack gets "popped", and the memory occupied for the current call is not released so much as abandoned, until it is overwritten by the next call that gets pushed into that part of the stack.

So why do we have to release variables like this:

MyClass *myObject = [[MyClass alloc] init];

Well, you actually don't have to worry about "myObject". It's on the stack, just like your ints, and it will get cleaned up when the current call finishes.

What you have to worry about is the memory that myObject—which is a pointer—points to. It's off somewhere on the heap. Constructing an object involves asking the runtime for some semi-permanent place to put it; that process returns a memory address, which your pointer stores.

alloc and release are Objective-C idioms that largely replace C's malloc() and free() functions, but all of them ultimately are asking the computer to set aside memory on the heap, and all of that memory must ultimately be returned, either through an autorelease pool, a release message, or a free() call.

Seamus Campbell
+1 for this sentense: "Well, you actually don't have to worry about "myObject". It's on the stack, just like your ints, and it will get cleaned up when the current call finishes.". This fact is important to mention since a lot of unexperienced people don't get it.
monoceres
One other thing worth pointing out: ints and other values of primitive types are not Cocoa or CF objects, which is why (1) you don't manage them the same way you do Cocoa and CF objects (they don't have retention counts), (2) you can't send them any messages at all, and (3) you can't put them directly into any Cocoa or CF collection objects; you must wrap them in value objects such as NS/CFNumber or NS/CFString and put those into your collections. NSInteger, NSUInteger, CFIndex, and CGFloat are just other names (typedefs) of primitive types, so all of this is true of them, too.
Peter Hosey
If you create an object with alloc init inside a function call do you have to release it in that function call or will it automatically be dealt with like the local variables?
awakeFromNib
@awakeFromNib: you do have to release the object before it goes out of scope. This is why the answer is slightly misleading. You don't release the ints because they are local variables but because they are not Objective-C objects.
JeremyP
Local variables are automatically dealt with. The pointer to your object is a local variable. It will be automatically dealt with. The object it _points to_ is not local and must be released.
Seamus Campbell
+2  A: 

int is what is known as a primitive type. It is not a pointer to an Objective-C object so you cannot release it. You can't even send a message to it.

NSInteger is also a primitive type in the sense that it is a typedef to a primitive type (long usually). So you can't release that either.

What do you need to release? You need to release any object you obtained by sending new, alloc or a method containing copy. You also need to release objects to which you have sent retain. So all of the local variables in the following must be released:

-(void) foo
{
    NSString* aString  = [[NSString alloc] init];
    NSString* aString2 = [aString copy];
    NSString* aString3 = [someOtherString retain];
    NSString* aString4 = [@"some string" copy];
}

NB due to implementation details, you would actually get away with not releasing the aString4 but you don't need to worry about it.

JeremyP