• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Memory allocation questions
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Memory allocation questions


  • Subject: Memory allocation questions
  • From: Terry Simons <email@hidden>
  • Date: Sat, 27 Jul 2002 22:52:25 -0600

I just finished reading "Object-Oriented Programming and the Objective-C Language"

I'm confused about a lot of the Apple runtime stuff, but I'll tackle the confusion one subject at a time. ;)

The ObjectiveC language all by itself doesn't seem too complicated, but I'm confused when it comes to the memory management aspects that are part of Apple's runtime.

It seems like this is a very common problem for people new to Cocoa, but I couldn't find the answers to my specific questions in the lists.

I understand the idea that a count is held for objects, but I don't understand when I should call retain/copy/autorelease/release.

From the docs:

"If you create an object (using alloc or allocWithZone:) or copy an object (using copy, copyWithZone:, mutableCopy, or mutableCopyWithZone:), you alone are responsible for releasing it"

This makes sense. If you allocate memory, you should release it. It sounds a lot like malloc/free or new/delete. So far so good.

Later in the docs:

"When you write a method that creates and returns an object, that method is responsible for releasing the object. However, it's clearly not fruitful to dispose of an object before the recipient of the object gets it. What is needed is a way to mark an object for release at a later time, so that it will be properly disposed of after the recipient has had a chance to use it. Cocoa provides just such a mechanism."

Ok, that makes some sense. Enter autorelease:

"By autoreleasing an object-that is, by sending it an autorelease message-you declare that you don't need the object to exist beyond the scope you sent autorelease in."

I'm assuming that scope here means essentially the same thing as in standard C/C++? If I declare something in a method, it dies at the end of the method's scope, and you should release any memory you've allocated in the method?

If so, then in method "sprockets" from the docs:

- (NSArray *)sprockets
{
NSArray *array;

array = [[NSArray alloc] initWithObjects:mainSprocket,
auxiliarySprocket, nil];
return [array autorelease];
}

Ok, so autorelease is called. We use autorelease in this instance so we're not destroying the data before it reaches the calling code, correct? Essentially, a "release" here would deallocate the memory that array was pointing at, correct? We don't want that, so we autorelease.

What *exactly* does autorelease do differently than release?

Does it play with the counter that determines when to release an object? Does it do more?

The next paragraph from the docs:

"When another method gets the array of Sprockets, that method can assume that the array will be disposed of when it's no longer needed, but can still be safely used anywhere within its scope (with certain exceptions; see "Validity of Shared Objects" ). It can even return the array to its invoker, since the application object defines the bottom of the call stack for your code. The autorelease method thus allows every object to use other objects without worrying about disposing of them."

Now... does this NSArray get disposed of at the end of the scope of the function it got returned to, or does it live for the life of the application?

At first glance, I would assume that it is for the life of the method scope. "...that method can assume that the array will be disposed of when it's no longer needed, but can still be safely used anywhere within its scope..." Which goes back to my question of whether "scope", in this case, is the scope of the method, as it would be in C, or if it's something specific to ObjC. Does it mean application scope? The next thought from the above paragraph confuses me:

"It can even return the array to its invoker, since the application object defines the bottom of the call stack for your code. The autorelease method thus allows every object to use other objects without worrying about disposing of them."

What does the term "invoker" mean in this sentence? "since the application object defines the bottom of the call stack for your code" also confuses me.

That's why I asked above if the object lives for the life of the application, though I don't think that's right...

Now... if I did return this array again, would I have to issue a retain when I return the object? If the object lives in method scope only, then it would seem so.... because if autorelease works the way I think it does, then after each "scope hop" the counter for the object in the release pool gets decremented? If not, can someone explain what autorelease does?

If it does get decremented at each scope hop, then a retain would be necessary for each "return"? So.... return [array retain];?

But would you have to autorelease it again? So.... return [ [array retain] autorelease];? (That seems awfully redundant)

I'd like to get a firm understanding of how this stuff works before I jump in with both feet. :)

I'm also confused about the retain, and autorelease in the following method, also an example in the docs:

- (void)setMainSprocket:(Sprocket *)newSprocket
{
[mainSprocket autorelease];
mainSprocket = [newSprocket retain]; /* Claim the new Sprocket. */
return;
}

My attempt at understanding the above method:

First Line:
mainSprocket needs to get autoreleased because we're going to change it's value? (Why not use release instead of autorelease in this example?)

Second Line:
mainSprocket gets newSprocket, retain the contents, because the function that passed in the data should have autoreleased it?

One more:

- (void)setMainSprocket:(Sprocket *)newSprocket
{
[mainSprocket autorelease];
mainSprocket = [newSprocket copy]; /* Get a private copy. */
return;
}

I'm assuming that mainSprocket is basically getting a copy of all of the values stored in newSprocket?
This seems like a (sorry for likening this to another language) C++ copy constructor. Is that a close approximation?


Ugh... this stuff makes my brain hurt.

Thanks,

- Terry
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.

  • Follow-Ups:
    • Re: Memory allocation questions
      • From: Ondra Cada <email@hidden>
    • Re: Memory allocation questions
      • From: Finlay Dobbie <email@hidden>
    • Re: Memory allocation questions
      • From: Nathan Day <email@hidden>
    • Re: Memory allocation questions
      • From: Jeff LaMarche <email@hidden>
  • Prev by Date: Is there a convention...
  • Next by Date: Cocoa Doc Typo
  • Previous by thread: Re: Is there a convention...
  • Next by thread: Re: Memory allocation questions
  • Index(es):
    • Date
    • Thread