views:

5094

answers:

9

I come from a C/C++ background and the dynamic nature of ObjectiveC is somewhat foreign to me, is there a good resource anyone can point me to for some basic memory management techniques in ObjectiveC? ex. retaining, releasing, autoreleasing

For instance, is it completely illegal to use a pointer to an Objective C object and treat it as an array? Are you forced to use NSArray and NSMutableArray for data structures?

I know these are pretty newbie questions, thanks for any help you can offer me.

+2  A: 

If it's an array, feel free to iterate with a pointer. Regular arrays are still governed by C. If it's a NSArray, read the NSArray docs. If they say to do it a particular way, do it that way. When writing for OS X, do it by the book.

Kevin Conner
+2  A: 

Objective-C is just a superset of C. Anything you can do in C is valid in Objective-C.

craigb
+2  A: 

You can certainly use arrays and do your own memory management. The biggest component is that if you're creating anything that's an NSObject subclass, and you create it with a [XXX alloc] method, or if you get it from another copy with [xxx copy], then you've got the responsibility to match that with an associated release.

If get a variable from anywhere and intend to keep it around for more than the immediate usage that you're executing through, then make sure you invoke a [... retain] on it.

The link http://developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html has all the details, and is definitely the first place to read.

heckj
A: 

It's probably also useful to note that for class messages like NSString + (NSString *)stringWithFormat: (basically, helper messages that allocate an object for you rather than requiring you to allocate the object yourself), the resulting object is auto-released unless you explicitly retain it.

A: 

Here are the rules:

  1. If you create an object by calling alloc or copy, you own it and must release it when you're done.
  2. If you didn't create an object, but want it to ensure it sticks around before control returns to the run loop (or, to keep things simple, your method returns), send it a retain message and then release it later when you're done.
  3. If you create an object and want to return it from your method, you are obligated to release it, but you don't want to destroy it before the caller gets a chance to see it. So you send it autorelease instead, which puts it in the Autorelease Pool, which is emptied once control gets back to the program's event loop. If nobody else retains the object, it will be deallocated.

Regarding arrays, you are free to do something like this:

NSObject *threeObjects[3];

threeObjects[0] = @"a string";
threeObjects[1] = [NSNumber numberWithInt:2];
threeObjects[2] = someOtherObject;

Reasons to use NSArray anyway:

  • NSArray will take care of retaining objects as you add them and releasing them as you remove them, whereas in a plain C array you will have to do that yourself.
  • If you are passing an array as a parameter, an NSArray can report the count of objects it contains, with a plain C array you'll need to pass a count along too.
  • Mixing square bracket meanings on one line feels weird:

    [threeObjects[0] length]

benzado
The rules given here are incomplete (omitting the *copy* and new* patterns for ownership) -- see Apple's documentation for the complete correct rules.
mmalc
The assertion "which puts it in the Autorelease Pool, which is emptied once control gets back to the program's event loop" is not necessarily correct. Autoreleased objects are added to *the current top-most autorelease pool*, which may be local to a method or a thread.
mmalc
+11  A: 

It is generally not useful to repeat the basic rules of memory management, since almost invariably you make a mistake or describe them incompletely -- as is the case in the answers provided by 'heckj' and 'benzado'...

The fundamental rules of memory management are provided in Apple's documentation in Memory Management Rules.

Apropos of the answer from 'www.stray-bits.com': stating that objects returned from "non-owning" methods are "autoreleased" is also at best misleading. You should typically not think in terms of whether or not something is "autoreleased", but simply consider the memory management rules and determine whether by those conventions you own the returned objet. If you do, you need to relinquish ownership...

One counter-example (to thinking in terms of autoreleased objects) is when you're considering performance issues related to methods such as stringWithFormat:. Since you typically(1) don't have direct control over the lifetime of these objects, they can persist for a comparatively long time and unnecessarily increase the memory footprint of your application. Whilst on the desktop this may be of little consequence, on more constrained platforms this can be a significant issue. It is therefore considered best practice on all platforms to use the alloc/init pattern, and on more constrained platforms, where possible you are strongly discouraged from using any methods that would lead to autoreleased objects.

(1) You can take control by using your own local autorelease pools. For more on this, see Apple's Memory Management Programming Guide.

mmalc
Comment on my answer if I got something wrong, so I can fix it or at least other people will know what's wrong.
benzado
When I first added my answer, I didn't have enough points to comment...
mmalc
+1  A: 

Something to be aware of if you use an C-style array to store objects and you decide to use garbage collection is you'll need to allocate that memory with NSAllocateCollectable(sizeof(id)*size, NSScannedOption) and tag that variable as __strong.

This way the collector knows that it holds objects and will treat objects stored there as roots during that variables lifetime.

Ashley Clark
+1  A: 

For instance, is it completely illegal to use a pointer to an Objective C object and treat it as an array?

If it's not an array, then yes.

Are you forced to use NSArray and NSMutableArray for data structures?

No. You can use C arrays, and you should be able to use C++ STL vectors (although I don't use C++, so I don't know specifics of how).

But there's no reason not to use NS{,Mutable}Array. Fear not the Cocoa frameworks, for they are your friend.

And don't forget the other collection types, such as NS{,Mutable}Set and NS{,Mutable}Dictionary.

Peter Hosey