Luca Carlon
Luca Carlon

Reputation: 9976

Autoreleasing in Objective-C application when returning a value

I read the memory management guide for the Objective-C language, but this is a doubt I still have, even after reading many times the chapter.

Let's say I want to return an object I just created in a method of an object like this:

NSString* ret = [[NSString alloc] initWithString:@"My string"];
return ret;

I can do this, but it is not correct according to the ownership policy. The guide states that the correct solution would be to:

NSString* ret = [[NSString alloc] initWithString:@"My string"];
return [ret autorelease];

because, as I'm autoreleasing, I'm no more the owner. My question is: when will the NSString be actually released and deallocated? When the last initialized pool is released? This means that, if I don't create a pool, this object will be released when the application is closed (the pool that xcode creates by default is released at the end). Is this correct? The same applies to objects which are not allocated by me like:

NSString* ret = [NSString stringWithString:@"My string"];

? If I don't create a pool to release it elsewhere, it is released at the end of the application when the pool created by xcode is released? Thanks for any clarification.

Upvotes: 0

Views: 612

Answers (3)

Chuck
Chuck

Reputation: 237010

Objects go into the current autorelease pool when they're autoreleased. When the pool itself is sent release (or drain, which is the same thing), the objects in it are also sent release. As for when the current autorelease pool will be created and released in most cases, the memory management guide chapter on autorelease says:

The Application Kit automatically creates a pool at the beginning of an event cycle (or event-loop iteration), such as a mouse down event, and releases it at the end

So in practice, autoreleased objects will go away very quickly — before the end of the app's lifetime, and in fact before the next touch/mouseMoved event message is sent.

It's possible to create your own local autorelease pool to make them go away even more immediately if you need to, but that's normally a micro-optimization that might actually make things go a bit slower (it increases the number of messages being sent without necessarily making anything else take less time).

Upvotes: 2

NSResponder
NSResponder

Reputation: 16861

Keep in mind that -autorelease is nothing but a delayed messaging facility. When you send -autorelease to an object, the current autorelease pool will add that object to its list, and when the pool is drained or released, it will send a -release message to every object in its list.

Upvotes: 1

walkytalky
walkytalky

Reputation: 9543

When you call autorelease, you're handing your ownership to the nearest autorelease pool, to be released at the next drain.

There must always be an outermost autorelease pool, but usually there will be other ones closer to the action. You don't have to create these explicitly -- though you can do that too -- they are created by the Cocoa framework in the course of going about the program's business.

If you're coding a non-GUI tool that never hands off to the framework, and you never create another pool, and never call drain on the existing one, then the object will be released when the pool itself is, just before exiting. Otherwise, it will most commonly be released at the end of the event handling cycle, which is one of the key places the framework maintains a pool.

In general, the case of objects created via convenience class methods is the same as those alloced and autoreleased. As it happens, the one you cite from NSString would be a little different because at its base is a constant string, and that doesn't get managed quite the same way. But that's an implementation detail.

Upvotes: 2

Related Questions