Reputation: 19727
What prevents the autoreleased instance of NSArray
from being released before it's used in the method it's returned to?
- (NSArray *) f {
return [NSArray array];
}
- (void) g {
NSArray *a = [self f];
// do something with a
}
Upvotes: 3
Views: 585
Reputation: 162712
What prevents the autoreleased instance of NSArray from being released before it's used in the method it's returned to?
Autorelease pools are per thread. That is, an autoreleased object is, effectively, a delayed call to release
that happens on a per thread basis.
Thus, if there is no call to drain
between the caller and the callee, there is no way the autoreleased object will be released because of a pool drain (barring serious threading stupidity).
In general, pools are drained at very well specified times, like Kevin said:
• the run loop will drain the pool at the bottom of each pass through the loop
• dispatched blocks via GCD will execute within a pool context that'll be drained "every now and then" (implementation detail). NSOperationQueue behaves similarly
• other threads are responsible for doing it themselves
Thus, in your simple example, the code execution is quite linear and, by inspection, there can be no drain in that thread of execution between the return and the use in the caller.
(Note that this is also one of the reasons why retainCount
is useless; it neither accounts for any "delayed release" calls caused by autorelease
nor does it quantify any per-thread retains. In reality, you should think of retains/releases as being entirely per-thread; if you retain an object on a thread you should release it on the same thread unless you are explicitly transferring ownership from one thread to another.)
Upvotes: 5
Reputation: 185661
Autoreleased objects are only released when their surrounding pool is drained. This is not some magical process that happens behind the scenes. It's a deterministic event that happens at well-defined times. In general, the pool is drained when control returns to the run loop. If you establish your own nested pool, then you control when that drains.
Upvotes: 4
Reputation: 31016
The autorelease pool is drained during an iteration of the event loop. Since it's that drain that causes release messages to be sent to the autoreleased objects, they are still valid in the calling method.
Upvotes: 2