What is the difference between releasing and autoreleasing?
Releasing means you release that right away. Autoreleasing means you want the variable to be released on the next autorelease pool.
You use autorelease when you want to keep retaining the variable but don't want to create a memory leak. You use release when you don't need the variable anymore.
Sample:
- (NSNumber *)return5 {
NSNumber * result = [[NSNumber alloc]initWitnInt: 5];
[result autorelease];
return result;
}
Why do we use autorelease there?
If we use [result release] instead, variable result will be destroyed AT that time. Which means that the returned value will be garbage.
If we do not release at all, variable result
will be hold FOREVER incurring memory leak.
We can tell every caller to the function to release result but that would be a headache and prone to error.
So we use autorelease. We mark the variable to be released on the next autorelease pool. Basically we mark the variable to be released near the alloc. Hence the mantra alloc is paired with release in the same function holds all the time.
Actually, you'll do fine changing all release into autorelease. Your memory use won't be efficient, however, the effect is minimal. All variables, in all programming language is effectively autoreleased.
Anyway, use ARC.
background discussion:
objective-c is reference counted, so objects are deleted when the reference count reaches 0. release reduces the reference-count immediately, autorelease reduces it when the autorelease-pool is popped
when to use:
use autorelease when allocating the object if
- you do not need it after the current function
- it will be retiained by some other objet/function and will be released by a later by the retaining code
- when the logic of the current function is tricky, so you would have to send release in a dozen different places before doing a return
use "manual" release
- to revert a previous retain (in case you are implementing a library)
- if you need precise control of freeing objects (e.g. they use lots of memory or the autorelease pool will not be popped for some time)
but really my freand:
- read the Memory Management Programming Guide for Cocoa as suggested by Barry and run your code with instruments (zombies and leaks) often to catch any and almost all memory management errors.
Erik
The Memory Management Programming Guide for Cocoa will soon be your best friend. In brief, object instances in Cocoa are memory managed using reference counting (unless, of course you're using garbage collection on OS X). An object indicates that it wants to 'retain' an ownership interest in an other instance--keep it from being deallocated--by sending it a -retain
message. An object indicates that it wants to release that interest by sending the other instance a -release
message. If the number of objects that have 'retained' and ownership interest in an object drops to 0 (i.e. when the last of the owning instances sends a -release
message), the instance with a 0 retain count is deallocated.
It's sometimes convenient to say "I want this instance to be released some time in the future". That's the purpose of -autorelease
. Sending an -autorelease
message adds the receiver to the current NSAutoreleasePool
. When that pool is drained, it sends a -release
message to all the instances in the pool. An NSAutoreleasePool
is automatically created at the start of each iteration of each thread's run loop and drained at the end of that iteration. Thus, you can do something like this in a method:
- (id)myMethod {
return [[[MyObject alloc] init] autorelease];
}
The caller of this method will get back an instance that they can -retain
if they wish to keep it. If they don't retain it, it will stick around at least until the enclosing autorelease pool is drained:
- (void)someOtherMethod {
...
id instance = [obj myMethod];
... // do more with instance, knowing that it won't be dealloc'd until after someOtherMethod returns
}