简体   繁体   中英

iOS memory management confused

I have a static method in a Utilities class:

+ (Division *) getDefaultDivision
{
    Division *defaultDivision = [[Division alloc] init];
    defaultDivision.Id = 0;
    defaultDivision.name = @"Accounting";
    defaultDivision.slug = @"accounting";

    return defaultDivision;
}

And in my ViewController I do something like:

Division *div = [[Division alloc] init];
div = [Utilities getDefaultDivision];

But when I analyze, it says "Potential leak of an object allocated on line x and stored into defaultDivision".

If I use:

Division *defaultDivision = [[[Division alloc] init] autorelease];

it works once, but when I use it again, it crashes.

Just wondering what the proper thing is to do here?

If this is your real code;

Division *div = [[Division alloc] init];
div = [Utilities getDefaultDivision];

You're first allocating a Division and saving it in div, then you're getting a new one from getDefaultDivision storing that in div too without releasing the first one.

Regardless of how "getDefaultDivision" is implemented, you have a leak in this code:

Division *div = [[Division alloc] init];
div = [Utilities getDefaultDivision];

Line 1 allocates memory and assigns div to point to that memory. You must free this memory at some point. But after line 2, that becomes impossible, because div is now has a new value -- and the pointer to the memory allocated in line 1 is lost . This is a leak. Until you understand why, you are on thin ice.

As for this method:

+ (Division *) getDefaultDivision
{
    Division *defaultDivision = [[Division alloc] init];
    defaultDivision.Id = 0;
    defaultDivision.name = @"Accounting";
    defaultDivision.slug = @"accounting";
    return defaultDivision;
}

This is sometimes called a "factory" method -- a static utility method for allocating, initializing, and returning reference to a new instance of a class. The best practice here is to use autorelease in factory methods. Eg:

Division *defaultDivision = [[[Division alloc] init] autorelease];

Why is it a best practice? According to Apple's memory management guide, only methods with the following terms in them should return references to objects that the caller is responsible for releasing:

alloc, allocWithZone:, copy, copyWithZone:, mutableCopy, mutableCopyWithZone:

-- from http://developer.apple.com/library/IOs/#documentation/General/Conceptual/DevPedia-CocoaCore/MemoryManagement.html

Since "getDefaultDivision" is not an "alloc" or "copy" method (it is an accessor method), then it should not return a pointer to an object which the caller must later free to avoid a leak. Marking the newly allocated returned memory as autorelease is one way to follow this contract.

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