views:

929

answers:

7

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.

+6  A: 

See this SO topic(duplicate?):

http://stackoverflow.com/questions/106627/memory-management-in-objective-c

arul
+1  A: 

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.

Marc Charbonneau
Also note that the iPhone OS doesn't support garbage collection.
Robert Gould
+1  A: 

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.

EightyEight
+3  A: 

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

Shawn Craver
thanks for the pointer to the "Hold me, use me, free me" article. it's a very good and simple explanation.
Nir Levy
But now it's broken.
Yar
yar: I've changed the link to go to the Internet Archive's copy.
Peter Hosey
A: 

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.

Ian Turner
+1  A: 

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.

Georg
A: 

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.

Justin
On the other hand, doing `[[alloc] init]`, not `[[[alloc] init] autorelease]`, makes it *very* easy to forget the `release` message that the former requires.
Peter Hosey
@Peter I'd say it is initally an easier mistake to make (as opposed to '*very* easy'), but it's a change that is learned easily. Again, problems are either generally immediate or (in the case of leak detection and static analysis) lead to the problem areas, rather than setting a breakpoint in the initializer and tracking who creates what, where, when... (p.s. thanks for Make RAM Disk)
Justin