tom
tom

Reputation: 14513

will call on release trigger the releasing of autorelease object?

For the following

NSImage *image = [[UIImage imageNamed:@"foo.png"] retain];
...
[image release];

My understanding is that the object returned from imageNamed supposedly will be autoreleased. But since there is a retain on the object and then an explicit release afterwards. The explicit release will not only reduce the ref count but also trigger the release of the whole object instead of waiting to be GC'd later. The assumption is that, when the release call is made, iOS will firstly try to reduce the ref count on the object, and then find out no body else is referencing the object at the time, so it decides to release the memory allocated. Is it correct understanding and assumption?

Upvotes: 1

Views: 351

Answers (3)

jscs
jscs

Reputation: 64002

There's no garbage collection as such. It's strictly the object counting its own references. When an object is created, it gives itself a reference count of 1. In this case though, the method that creates the object -- imageNamed: -- puts the object into an autorelease pool. That means that the pool is the owner of the 1 reference, and it will auto matically release the reference at a later time (after this method has finished).

When an object's reference count drops to 0, it destroys itself, by running its dealloc method.

Your sending retain to the image (which is owned by the autorelease pool) means that there is another reference -- another owner -- (the count then would be 2, but you should really not think about the object's internal absolute number, just about your ownership).

The pool will still send release when it was going to anyways, but (if you have not released the ownership claim you got by sending retain), this release by itself will not drop the ref count to 0, so the object will not be destroyed.

Since you do send release, you've given up your claim, and the autorelease pool will take care of its ownership -- but still later, not right when you send release -- leading to the image's destruction.

In short, no, your sending of release does not change the autorelease pool's action. It still owns the object, and still sends release to it at the end of the run loop.

Upvotes: 1

Jody Hagins
Jody Hagins

Reputation: 28409

No, that is not correct.

Furthermore, you are playing a bit loose with the memory management terms, so your questions are a bit confusing.

A detailed discussion of all these aspects are too much for a SO post.

An auto release pool is not garbage collection. Think of it as just a collection of objects. When you autorelease an object, the object is added to the pool. When the pool is drained, it basically calls release on each object in the pool (hence, the name autorelease pool).

Thus, if you have an object that has been autoreleased, and you make an extra retain call (with no matching release), the autorelease pool will not deallocate the object. It will just release it once like it is supposed to.

If you hold other references to the object, the object will still live on past the autorelease pool.

Calling retain/release multiple times just increments and decrements the count. The object does not dealloc until the count reaches zero.

Upvotes: 2

Matt Wilding
Matt Wilding

Reputation: 20153

That's not a correct assumption. The release will conceptually negate the retain. However, you can't know about any other ref counts that might be floating around out there. If your retain is the only one, then it will be immediately destroyed. That's certainly not the case.

Since we know that we're getting an autoreleased object, we know that our retain reference is not the only one. The original reference from the source of the autorelease will remain until the current autorelease pool is drained. Thus, your assumption is flawed here:

when the release call is made, iOS will firstly try to reduce the ref count on the object, and then find out no body else is referencing the object at the time, so it decides to release the memory allocated.

...because the reference from the original autorelease will remain.

Generally speaking, you shouldn't make any assumptions about exactly when an object will be dealloc'd. Just worry about balancing your own retain counts and trust that things will work out. In this example, it's also likely that there are far more references in existence than just your own retain and the assumed autorelease. The frameworks are free to retain and release all they want behind the scenes, as long as things remain balanced.

Finally, just use ARC and forget about all this :)

Upvotes: 1

Related Questions