Learn Obj-C Memory Management [duplicate] - iphone

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Where are the best explanations of memory management for iPhone?
I come from a web development background. I'm good at XHTML, CSS, JavaScript, PHP and MySQL, because I use all of those technologies at my day job.
Recently I've been tinkering with Obj-C in Xcode in the evenings and on weekends. I've written code for both the iPhone and Mac OS X, but I can't wrap my head around the practicalities of memory management. I understand the high-level concepts but am unclear how that plays out in implementation. Web developers typically don't have to worry about these sorts of things, so it is pretty new to me.
I've tried adding memory management to my projects, but things usually end up crashing. Any suggestions of how to learn? Any suggestions are appreciated.

On top of the official Apple resources listed in the post arul linked to, here are some other good reads on the topic:
Hold me, use me, free me
CocoaDev.com 's Memory Management Section
And for help debugging memory management problems:
NSZombieEnabled

Rules of thumb
Autorelease
Every time you have [[NSObject alloc] init] you wrap it into an autorelease:
// make sure it gets properly released
// autorelease releases the object at a later time.
NSObject *instance = [[[NSObject alloc] init] autorelease];
Things like this (can't remember the term) are always autoreleased, you should create your classes to correspond to this rule too:
NSString *test = [NSString stringWithFormat:#"%i", 4];
Retain / Release
If you need to store an object for longer than the current method retain it:
[instance retain];
If you don't need it anymore or exchanged it with another object:
[instance release];
You should always have the same amount of retains as releases in your code.
Accessors
Objective-C 2.0 let's you declare properties and writes your accessors for you. For example #property(retain, readwrite) NSString *text; looks something like this:
- (NSString *)text {
return text; // I don't like calling variables _test
}
- (void)setText:(NSString *)newText {
[newText retain];
[text release];
text = newText;
}
init / dealloc
In those methods you should always use [self setVariable:…] like this:
- (id)init {
if (self = [super init]) {
[self setText:#"Lorem ipsum dolor sit amet."];
// …
}
return self;
}
- (void)dealloc {
// make sure text is set to nil and the old value gets released.
[self setText:nil];
}
Garbage Collector
Use the Garbage Collector built into Objective-C 2.0, there's little gain from not using it if you can.
How does this retain / release work anyway?
Every time you allocate an object1, [NSObject alloc], the retain count is set to 1. If this count reaches 0 the object is deleted. [instance retain] increases the count by 1 and [instance release] decreases the count by 1.
1 [instance copy] does allocate a new instance too, and therefore also has a retain count of 1.

Memory management in Cocoa is actually pretty easy thanks to the retain / release paradigm. Start by learning the concept of pointers-- while you don't need to be an expert in C to learn objective-c, understanding pointers is essential. Then read this (or another) guide. Write down the rules if you need to on when you should and shouldn't retain an object, and with a little practice you should "get it" in no time.
Keep in mind you could turn on garbage collection and not worry so much about memory management, but I wouldn't recommend this; even with GC enabled there are still times when you have to understand what's going on behind the scenes.

Read the link that arul provided. Now that you're using a language that has no garbage collection (if you're developing for the iPhone) it's time to start thinking about object life times. Every object you instantiate will now have to be deallocated by someone, probably (possibly) you. Memory management is not an easy subject and the only way to get a handle on this is to practice. Play around with allocating an object and deallocating it. Watch the retain counts grow as you add an object to a collection. Look into Autorelease pools. Essentially, you should know where and when an object gets allocated AND deallocated. On systems with limited memory (such as iphone) you'd want an object to disappear as soon as possible.
My suggestion would be to spend a few days playing around with memory management before you start working on the bulk of your application. Debugging memory issues and struggling with application logic is a bit of a hassle.

One mistake I see often is the use of the autorelease convenience calls when a regular release will do. This only makes life difficult for you because this removes the problem from the call site, while making it very difficult to isolate problems in large codebases.
This also forces you to learn memory management from the outset, which is not fun, but worthwhile because you can generally salvage more of the code you've written.

I used the Memory Management video training course from the Mac Developer Network. Gave me exactly what I needed when I was starting out. It immediately paid benefits when I started having my own memory management problems.

Related

difference between ARC and MRC

I am confused with Apple material.
In 3 ways we manage the memory, they are :
automatic referance counting.
manual reference counting.
garbage colletion.
My doubt is what is the difference between automatic reference counting and manual referance counting.
Can someone explain me ?
In ARC you don't have to release/autorelease the memory allocated by you where as in case of manual you have to take care of this.
e.g. manual case
-(void)someMethod
{
NSMutableArray *arr = [[NSMutableArray alloc] init];
//use array
[arr release]; //when array is in no use
}
ARC case
-(void)someMethod
{
NSMutableArray *arr = [[NSMutableArray alloc] init];
//use array
}
In ARC the OS looks after the memory management, so you don't have to worry about releasing the objects. It's pretty neat for beginners. Whereas in Manual counting you will have to keep track of releasing the memory and if you don't do it right you will end up crashing your app. ARC and MRC are available in ios where as garbage collection is limited to MAC-OSX hope this helps. Inder has given a good example.
In MRC, you were responsible for keeping track and making sure that all references of objects were incremented, decremented and deallocated properly. In Obj-C you have basically a set of rules to help you not get any memory leaks or dangling pointers, and it was a considerable effort to make sure that everything was working great, and that could've been automated by something, like some other languages used to.
That's is when ARC get's into the game.
ARC came as an incisive alternative to how things worked with MRC. With ARC, instances are deallocated when there's no strong reference to them, and every instance keeps track of the number of strong and weak/unowned references kept to itself. Although it might look like a similar behaviour, the amount of effort used in both cases are hugely different, in MRC you had to keep track of everything, whereas in ARC the only thing you should do is avoid retain cycles.
Some differences between ARC and Garbage Collector are:
Garbage collector is part of the runtime structure. In ARC, the Swift compiler does code-cleaning and reference tracking insertion in your app bundle.
Garbage collector does not reclaims the memory as soon as the instance loses its references, ARC does.
If some objects cycle (or graph) has references to themselves, but are not accessible through the root node, GC can clean the hole graph, whereas in ARC they would never get deallocated because they hold strong references to it other(retain cycle).
If you want to check for more information, I've found this article to be very helpful:https://swift007blog.wordpress.com/2017/01/14/what-is-arc-in-ios/
MRC vs ARC
ARC inserts retain, release, autorelease instead of developer in compile time. Now you don't worry about manual memory management
[Under the hood]

iPhone: using retain vs autorelease

Which one of these is better practice?
A) retain and release the object myself later
NSMutableArray* array = [[self getArray] retain];
....
[array release];
B) autorelease from the function returning the object
getArray {
NSMutableArray* returnedArray = [[[NSMutableArray alloc] init] autorelease];
.....
return returnedArray;
}
The simplest rule of thumb when it comes to memory management in Objective-C is that you should release anything that you've explicitly allocated (alloc), copied (copy), newed up (new), or retained (retain).
The release should be done within the scope of the aforementioned actions. If you allocate space for an object that is returned by a method, you should autorelease it before returning it. So, given the two options you've provided, B is the recommended practice.
You could read and follow Apples guidelines on memory management and performance.
Personally I think the reasons for choosing one way over the other:
Using Autorelease pros:
You can't stuff it up, memory will be freed at some point. That I like to think of as "falling into the pit of success".
cons:
Using autorelease a lot may cause you memory problems as lots of objects build up awaiting be released by the autorelease pools.
Using retain/release pros:
More control when your memory is used/freed.
On ios apple recommends that you use release instead of autorelease whenever possible to keep the size of the pool small.
cons:
Like C/C++ malloc/free new/delete you have to be careful to keep them matched up and it is easy to stuff that up, causing memory leaks.
For member variables you have no choice, retain/release is it.
I think, whichever style you choose comes down to the situation your code is in and choosing the best style based on there pro's and con's. I don't think there is any one answer to this.
If you want to return an object you have to use the second approach. In all cases where possible you should use the retain-release approach because this uses less memory.
If you new, alloc init, retain, or copy (NARC) an object, you have to release it.
When the name of a method starts with any of those words, it means it's being created for the caller, who has the responsibility to release the object when he is done with it.
Otherwise the method returned is not owned by the caller, and he has to indicate he wants to keep it calling retain on the object.
If you can choose, don't abuse autorelease when memory is a concern.
Some comments:
The first rule logically results in the second. Example: if the outcome of a function (the returned object) survives the execution of the function, all the function can do is autorelease the object.
Unless there is a memory/performance concern, the overhead of automatic memory management is better than the memory leak chances plus the increased developing time.
Try to retain/release symmetrically. Example: if you retained on init, then release on dealloc. Same for viewDidLoad/viewDidUnload.
If you use #property(retain) you have to release in dealloc.
Example:
// created with autoreleased, just call retain if you intend to keep it
NSString *orange = [NSString stringWithString:#"orange"];
// created for the caller, you'll have to release it when you are done
NSObject *apple = [NSString initWithString:#"apple"];

Suggest the best way of initialization of array ( or other objects )

I am a bit confused in the following two ways of initialisations.....
Way 1:
- (void) myMethod{
NSArray *myArray = [[NSArray alloc] initWithObjects:obj1,obj1,nil];
[self setClassArray:myArray];
[myArray release];
}
Way 2:
- (void) myMethod{
NSArray *myArray = [NSArray arrayWithObjects:obj1,obj2,nil];
[self setClassArray:myArray];
}
In way 1, I have used a alloc init method which is a instance method and as I have used an alloc statement I have to release the array myself.
In way 2, I have used a static method to initialze the array and as there is no alloc statement used I dont need to release the memory the system will take care of that.
Way 1, is time consuming and can to lead to memory leaks if not taken care
Way 2, is faster in writing and you dont need to take care of memory leaks
But , still i have seen the way1 used in standard source codes more often than the way2. I have no idea why people do this or if I am wrong at some place.
Answers and comments are oppenly invited. Please suggest the best programming practice.
Your second example uses a convenience constructor, which returns an autoreleased object. The question, then, is whether it's better to use autorelease or alloc/release. mmalc's answer on this StackOverflow thread explains the drawbacks of autoreleasing objects. (Basically, use alloc/release whenever possible.)
Also (this may be stating the obvious), some classes might not have convenience constructors, so when working with these you'd have to use alloc/release.
as i know,
[NSArray arrayWithObjects:obj1,obj2,nil];
returns an autoreleased object, smth like
[[[NSArray alloc] initWithObjects:obj1,obj1,nil] autorelease];
and I prefer not to manage memory with autorelease pool. maybe it's just a prejudice))
When using method 2 (autorelease) the object is released when the operating system feels it has no references.
But when using the manual release, as you typed in your code, you can release directly, or whenever you need to.
I usually prefer the second way, and if I recall correctly, this is also what the Apple docs reccommend (use autorelease where possible).
In Way 1 the memory gets released faster, so if you have a method that gets called in a loop or recursively, using autorelease may accumulate much memory, whereas alloc/retain will keep your memory footprint low.
On the other hand I assume that using autorelease is more efficient, because the autorelease pool can release a big chunk of memory at once, instead of small chunks again and again. Tough I may be wrong here.

Use autorelease before adding objects to a collection?

I have been looking through the questions asked on StackOverflow, but there are so many about memory management in Objective-C that I couldn't find the answer I was looking for.
The question is if it is ok (and recommnded) to call autorelease before adding a newly created object to a collection (like NSMutableArray)? Or should I release it explicitly after adding it. (I know NSMutableArray willl retain the object)
This illustrates my question:
Scenario A (autorelease):
- (void) add {
// array is an instance of NSMutableArray
MyClass *obj = [[[MyClass alloc] init] autorelease];
[array addObject:obj];
}
Scenario B (explicit release):
- (void) add {
// array is an instance of NSMutableArray
MyClass *obj = [[MyClass alloc] init];
[array addObject:obj];
[obj release];
}
I assume both are correct, but I am not sure, and I sure don't know what the preffered way is.
Can the Objective-C gurus shed some light on this?
IMHO, which way is 'right' is a matter of preference. I don't disagree with the responders who advocate not using autorelease, but my preference is to use autorelease unless there is an overwhelmingly compelling reason not to. I'll list my reasons and you can decide whether or not their appropriate to your style of programming.
As Chuck pointed out, there is a semi-urban legend that there's some kind of overhead to using autorelease pools. This could not be further from the truth, and this comes from countless hours spent using Shark.app to squeeze the last bit of performance out of code. Trying to optimize for this is deep in to "premature optimization" territory. If, and only if, Shark.app gives you hard data that this might be a problem should you even consider looking in to it.
As others pointed out, an autoreleased object is "released at some later point". This means they linger around, taking up memory, until that "later point" rolls around. For "most" cases, this is at the bottom of an event processing pass before the run loop sleeps until the next event (timer, user clicking something, etc).
Occasionally, though, you will need to get rid of those temporary objects sooner, rather than later. For example, you need to process a huge, multi-megabyte file, or tens of thousands of rows from a database. When this happens, you'll need to place a NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; at a well chosen point, followed by a [pool release]; at the bottom. This almost always happens in some kind of "loop batch processing", so it's usually at the start and bottom of some critical loop. Again, this should be evidence based, not hunch based. Instrument.app's ObjectAlloc is what you use to find these trouble spots.
The main reason why I prefer autorelease to release, though, is that it is much easier to write leak-free programs. In short, if you choose to go the release route, you need to guarantee that release is eventually sent to obj, under all circumstances. While this seems like it might be simple, it is actually surprisingly hard to do in practice. Take your example, for instance:
// array is an instance of NSMutableArray
MyClass *obj = [[MyClass alloc] init];
[array addObject:obj];
// Assume a few more lines of work....
[obj release];
Now imagine that for some reason, something, somewhere, subtly violates your assumption that array is mutable, maybe as the result of using some method to process the results, and the returned array containing the processed results was created as a NSArray. When you send addObject: to that immutable NSArray, an exception will be thrown, and you will never send obj its release message. Or maybe something goes wrong somewhere between when obj was allocd and the required call to release, like you check some condition and return() immediately by mistake because it slipped your mind that that call to release later on must take place.
You have just leaked an object. And probably signed yourself up to several days of trying to find out where and why it is your leaking it. From experience, you will spend many hours looking at that code above, convinced that it could not possibly be the source of the leak because you very clearly send obj a release. Then, after several days, you will experience what can only be described as a religious epiphany as you are enlightened to the cause of the problem.
Consider the autorelease case:
// array is an instance of NSMutableArray
MyClass *obj = [[[MyClass alloc] init] autorelease];
[array addObject:obj];
// Assume a few more lines of work....
Now, it no longer matters what happens because it's virtually impossible to leak obj accidentally, even under extremely unusual or exceptional corner cases.
Both are correct and will work as you're expecting them to.
I personally prefer to use the latter method, but only because I like to be explicit about when objects get released. By autoreleasing the object, all we're doing is saying "this object will get released at some arbitrary point in the future." That means you can put the autoreleased object into the array, destroy the array, and the object might (probably) still exist.
With the latter method, the object would get destroyed immediately with the array (providing that nothing else has come along and retained it in the meantime). If I'm in a memory-constrained environment (say, the iPhone) where I need to be careful about how much memory I'm using, I'll use the latter method just so I don't have so many objects lingering in an NSAutoreleasePool somewhere. If memory usage isn't a big concern for you (and it usually isn't for me, either), then either method is totally acceptable.
They are both correct but B may be preferred because it has no overhead at all. Autorelease causes the autorelease pool to take charge of the object. This has a very slight overhead which, of course, gets multiplied by the number of objects involved.
So with one object A and B are more or less the same but definitely don't use A in scenarios with lots of objects to add to the array.
In different situations autoreleasing may delay and accumulate the freeing of many objects at the end of the thread. This may be sub-optimal. Take care that anyway autoreleasing happens a lot without explicit intervention. For example many getters are implemented this way:
return [[myObject retain] autorelease];
so whenever you call the getter you add an object to the autorelease pool.
You can send the autorelease message at any point, because it isn't acted on until the application's message loop repeats (i.e. until all your methods have finished executing in response to user input).
http://macdevcenter.com/pub/a/mac/2001/07/27/cocoa.html?page=last&x-showcontent=text
You have alloc'ed the object, then it's your job to release it at some point. Both code snippets work merely the same, correct way, with the autorelease way being the potentionally slower counterpart.
Personally speaking, I prefer the autorelease way, since it's just easier to type and almost never is a bottleneck.
They're both OK. Some people will tell you to avoid autorelease because of "overhead" or some such thing, but the truth is, there is practically no overhead. Go ahead and benchmark it and try to find the "overhead." The only reason you'd avoid it is in a memory-starved situation like on the iPhone. On OS X, you have practically unlimited memory, so it isn't going to make much of a difference. Just use whichever is most convenient for you.
I prefer A (autoreleasing) for brevity and "safety", as johne calls it. It simplifies my code, and I've never run into problems with it.
That is, until today: I had a problem with autoreleasing a block before adding it to an array. See my stackoverflow question:
[myArray addObject:[[objcBlock copy] autorelease]] crashes on dealloc'ing the array (Update: Turns out the problem was elsewhere in my code, but still, there was a subtle difference in behavior with autorelease…)

Understanding reference counting with Cocoa and Objective-C

I'm just beginning to have a look at Objective-C and Cocoa with a view to playing with the iPhone SDK. I'm reasonably comfortable with C's malloc and free concept, but Cocoa's references counting scheme has me rather confused. I'm told it's very elegant once you understand it, but I'm just not over the hump yet.
How do release, retain and autorelease work and what are the conventions about their use?
(Or failing that, what did you read which helped you get it?)
Let's start with retain and release; autorelease is really just a special case once you understand the basic concepts.
In Cocoa, each object keeps track of how many times it is being referenced (specifically, the NSObject base class implements this). By calling retain on an object, you are telling it that you want to up its reference count by one. By calling release, you tell the object you are letting go of it, and its reference count is decremented. If, after calling release, the reference count is now zero, then that object's memory is freed by the system.
The basic way this differs from malloc and free is that any given object doesn't need to worry about other parts of the system crashing because you've freed memory they were using. Assuming everyone is playing along and retaining/releasing according to the rules, when one piece of code retains and then releases the object, any other piece of code also referencing the object will be unaffected.
What can sometimes be confusing is knowing the circumstances under which you should call retain and release. My general rule of thumb is that if I want to hang on to an object for some length of time (if it's a member variable in a class, for instance), then I need to make sure the object's reference count knows about me. As described above, an object's reference count is incremented by calling retain. By convention, it is also incremented (set to 1, really) when the object is created with an "init" method. In either of these cases, it is my responsibility to call release on the object when I'm done with it. If I don't, there will be a memory leak.
Example of object creation:
NSString* s = [[NSString alloc] init]; // Ref count is 1
[s retain]; // Ref count is 2 - silly
// to do this after init
[s release]; // Ref count is back to 1
[s release]; // Ref count is 0, object is freed
Now for autorelease. Autorelease is used as a convenient (and sometimes necessary) way to tell the system to free this object up after a little while. From a plumbing perspective, when autorelease is called, the current thread's NSAutoreleasePool is alerted of the call. The NSAutoreleasePool now knows that once it gets an opportunity (after the current iteration of the event loop), it can call release on the object. From our perspective as programmers, it takes care of calling release for us, so we don't have to (and in fact, we shouldn't).
What's important to note is that (again, by convention) all object creation class methods return an autoreleased object. For example, in the following example, the variable "s" has a reference count of 1, but after the event loop completes, it will be destroyed.
NSString* s = [NSString stringWithString:#"Hello World"];
If you want to hang onto that string, you'd need to call retain explicitly, and then explicitly release it when you're done.
Consider the following (very contrived) bit of code, and you'll see a situation where autorelease is required:
- (NSString*)createHelloWorldString
{
NSString* s = [[NSString alloc] initWithString:#"Hello World"];
// Now what? We want to return s, but we've upped its reference count.
// The caller shouldn't be responsible for releasing it, since we're the
// ones that created it. If we call release, however, the reference
// count will hit zero and bad memory will be returned to the caller.
// The answer is to call autorelease before returning the string. By
// explicitly calling autorelease, we pass the responsibility for
// releasing the string on to the thread's NSAutoreleasePool, which will
// happen at some later time. The consequence is that the returned string
// will still be valid for the caller of this function.
return [s autorelease];
}
I realize all of this is a bit confusing - at some point, though, it will click. Here are a few references to get you going:
Apple's introduction to memory management.
Cocoa Programming for Mac OS X (4th Edition), by Aaron Hillegas - a very well written book with lots of great examples. It reads like a tutorial.
If you're truly diving in, you could head to Big Nerd Ranch. This is a training facility run by Aaron Hillegas - the author of the book mentioned above. I attended the Intro to Cocoa course there several years ago, and it was a great way to learn.
If you understand the process of retain/release then there are two golden rules that are "duh" obvious to established Cocoa programmers, but unfortunately are rarely spelled out this clearly for newcomers.
If a function which returns an object has alloc, create or copy in its name then the object is yours. You must call [object release] when you are finished with it. Or CFRelease(object), if it's a Core-Foundation object.
If it does NOT have one of these words in its name then the object belongs to someone else. You must call [object retain] if you wish to keep the object after the end of your function.
You would be well served to also follow this convention in functions you create yourself.
(Nitpickers: Yes, there are unfortunately a few API calls that are exceptions to these rules but they are rare).
If you're writing code for the desktop and you can target Mac OS X 10.5, you should at least look into using Objective-C garbage collection. It really will simplify most of your development — that's why Apple put all the effort into creating it in the first place, and making it perform well.
As for the memory management rules when not using GC:
If you create a new object using +alloc/+allocWithZone:, +new, -copy or -mutableCopy or if you -retain an object, you are taking ownership of it and must ensure it is sent -release.
If you receive an object in any other way, you are not the owner of it and should not ensure it is sent -release.
If you want to make sure an object is sent -release you can either send that yourself, or you can send the object -autorelease and the current autorelease pool will send it -release (once per received -autorelease) when the pool is drained.
Typically -autorelease is used as a way of ensuring that objects live for the length of the current event, but are cleaned up afterwards, as there is an autorelease pool that surrounds Cocoa's event processing. In Cocoa, it is far more common to return objects to a caller that are autoreleased than it is to return objets that the caller itself needs to release.
Objective-C uses Reference Counting, which means each Object has a reference count. When an object is created, it has a reference count of "1". Simply speaking, when an object is referred to (ie, stored somewhere), it gets "retained" which means its reference count is increased by one. When an object is no longer needed, it is "released" which means its reference count is decreased by one.
When an object's reference count is 0, the object is freed. This is basic reference counting.
For some languages, references are automatically increased and decreased, but objective-c is not one of those languages. Thus the programmer is responsible for retaining and releasing.
A typical way to write a method is:
id myVar = [someObject someMessage];
.... do something ....;
[myVar release];
return someValue;
The problem of needing to remember to release any acquired resources inside of code is both tedious and error-prone. Objective-C introduces another concept aimed at making this much easier: Autorelease Pools. Autorelease pools are special objects that are installed on each thread. They are a fairly simple class, if you look up NSAutoreleasePool.
When an object gets an "autorelease" message sent to it, the object will look for any autorelease pools sitting on the stack for this current thread. It will add the object to the list as an object to send a "release" message to at some point in the future, which is generally when the pool itself is released.
Taking the code above, you can rewrite it to be shorter and easier to read by saying:
id myVar = [[someObject someMessage] autorelease];
... do something ...;
return someValue;
Because the object is autoreleased, we no longer need to explicitly call "release" on it. This is because we know some autorelease pool will do it for us later.
Hopefully this helps. The Wikipedia article is pretty good about reference counting. More information about autorelease pools can be found here. Also note that if you are building for Mac OS X 10.5 and later, you can tell Xcode to build with garbage collection enabled, allowing you to completely ignore retain/release/autorelease.
Joshua (#6591) - The Garbage collection stuff in Mac OS X 10.5 seems pretty cool, but isn't available for the iPhone (or if you want your app to run on pre-10.5 versions of Mac OS X).
Also, if you're writing a library or something that might be reused, using the GC mode locks anyone using the code into also using the GC mode, so as I understand it, anyone trying to write widely reusable code tends to go for managing memory manually.
As ever, when people start trying to re-word the reference material they almost invariably get something wrong or provide an incomplete description.
Apple provides a complete description of Cocoa's memory management system in Memory Management Programming Guide for Cocoa, at the end of which there is a brief but accurate summary of the Memory Management Rules.
I'll not add to the specific of retain/release other than you might want to think about dropping $50 and getting the Hillegass book, but I would strongly suggest getting into using the Instruments tools very early in the development of your application (even your first one!). To do so, Run->Start with performance tools. I'd start with Leaks which is just one of many of the instruments available but will help to show you when you've forgot to release. It's quit daunting how much information you'll be presented with. But check out this tutorial to get up and going fast:
COCOA TUTORIAL: FIXING MEMORY LEAKS WITH INSTRUMENTS
Actually trying to force leaks might be a better way of, in turn, learning how to prevent them! Good luck ;)
Matt Dillard wrote:
return [[s autorelease] release];
Autorelease does not retain the object. Autorelease simply puts it in queue to be released later. You do not want to have a release statement there.
My usual collection of Cocoa memory management articles:
cocoa memory management
There's a free screencast available from the iDeveloperTV Network
Memory Management in Objective-C
NilObject's answer is a good start. Here's some supplemental info pertaining to manual memory management (required on the iPhone).
If you personally alloc/init an object, it comes with a reference count of 1. You are responsible for cleaning up after it when it's no longer needed, either by calling [foo release] or [foo autorelease]. release cleans it up right away, whereas autorelease adds the object to the autorelease pool, which will automatically release it at a later time.
autorelease is primarily for when you have a method that needs to return the object in question (so you can't manually release it, else you'll be returning a nil object) but you don't want to hold on to it, either.
If you acquire an object where you did not call alloc/init to get it -- for example:
foo = [NSString stringWithString:#"hello"];
but you want to hang on to this object, you need to call [foo retain]. Otherwise, it's possible it will get autoreleased and you'll be holding on to a nil reference (as it would in the above stringWithString example). When you no longer need it, call [foo release].
The answers above give clear restatements of what the documentation says; the problem most new people run into is the undocumented cases. For example:
Autorelease: docs say it will trigger a release "at some point in the future." WHEN?! Basically, you can count on the object being around until you exit your code back into the system event loop. The system MAY release the object any time after the current event cycle. (I think Matt said that, earlier.)
Static strings: NSString *foo = #"bar"; -- do you have to retain or release that? No. How about
-(void)getBar {
return #"bar";
}
...
NSString *foo = [self getBar]; // still no need to retain or release
The Creation Rule: If you created it, you own it, and are expected to release it.
In general, the way new Cocoa programmers get messed up is by not understanding which routines return an object with a retainCount > 0.
Here is a snippet from Very Simple Rules For Memory Management In Cocoa:
Retention Count rules
Within a given block, the use of -copy, -alloc and -retain should equal the use of -release and -autorelease.
Objects created using convenience constructors (e.g. NSString's stringWithString) are considered autoreleased.
Implement a -dealloc method to release the instancevariables you own
The 1st bullet says: if you called alloc (or new fooCopy), you need to call release on that object.
The 2nd bullet says: if you use a convenience constructor and you need the object to hang around (as with an image to be drawn later), you need to retain (and then later release) it.
The 3rd should be self-explanatory.
Lots of good information on cocoadev too:
MemoryManagement
RulesOfThumb
As several people mentioned already, Apple's Intro to Memory Management is by far the best place to start.
One useful link I haven't seen mentioned yet is Practical Memory Management. You'll find it in the middle of Apple's docs if you read through them, but it's worth direct linking. It's a brilliant executive summary of the memory management rules with examples and common mistakes (basically what other answers here are trying to explain, but not as well).