简体   繁体   中英

Does this Objective-C code leak memory?

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];

}

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.

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.

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

Objects you initialize, however, like NSString or NSArray will usually have to be released (unless they are autoreleased, like the NSString s 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...

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM