11

Possible Duplicates:
Learn Obj-C Memory Management
Where are the best explanations of memory management for iPhone?

I come from a C/C++ background and the dynamic nature of Objective-C is somewhat foreign to me, is there a good resource anyone can point me to for some basic memory management techniques in Objective-C? 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.

Community
  • 1
  • 1

10 Answers10

19

Here you go:

Application memory management is the process of allocating memory during your program’s runtime, using it, and freeing it when you are done with it. A well-written program uses as little memory as possible. In Objective-C, it can also be seen as a way of distributing ownership of limited memory resources among many pieces of data and code. When you have finished working through this guide, you will have the knowledge you need to manage your application’s memory by explicitly managing the life cycle of objects and freeing them when they are no longer needed.

Although memory management is typically considered at the level of an individual object, your goal is actually to manage object graphs. You want to make sure that you have no more objects in memory than you actually need...

gnat
  • 6,213
  • 108
  • 53
  • 73
Ben Hoffstein
  • 102,129
  • 8
  • 104
  • 120
13

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
  • 8,201
  • 3
  • 39
  • 39
  • 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 Oct 02 '08 at 00:51
  • 1
    When I first added my answer, I didn't have enough points to comment... – mmalc Oct 03 '08 at 15:28
2

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.

easeout
  • 8,665
  • 5
  • 43
  • 51
2

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

craigb
  • 16,827
  • 7
  • 51
  • 62
2

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
  • 7,136
  • 3
  • 39
  • 50
2

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
  • 82,288
  • 22
  • 110
  • 138
  • The rules given here are incomplete (omitting the *copy* and new* patterns for ownership) -- see Apple's documentation for the complete correct rules. – mmalc Oct 03 '08 at 15:32
  • 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 Oct 03 '08 at 15:34
1

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
  • 8,813
  • 3
  • 35
  • 35
1

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
  • 95,783
  • 15
  • 211
  • 370
  • Iterating C arrays is a lot faster. Of course there's no reason to optimize until there is a need to optimize. Also just to clarify, you can refer Objective-C objects using a (C style) array of pointers. –  Jan 08 '12 at 21:03
1

As another fellow newbie, I found the stanford iOS lectures to be very useful: http://itunes.apple.com/itunes-u/developing-apps-for-ios-hd/id395605774

It's good because it shows the concepts in action with demos, and I generally find someone speaking to me absorbs better than just reading.

I definitely think it's one of those topics you have to learn and relearn through different sources though....just to hammer it into your head.

zlog
  • 3,316
  • 4
  • 42
  • 82
0

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.

user20456
  • 11
  • 1