8

Recently I've begun to code in Objective-C for iOS 5 devices. My brand new MacBook is loaded with Xcode 4.2 and the latest Mac & iOS SDKs. So far it's been a fun experience but there is one problem that I see with the current state of documentation and available books.

Specifically, most books (that have yet to be updated) always reference how and when to manage your memory. This is great, however, the current SDK/compiler includes Automatic Reference Counting and since I leave this turned on for my projects, I have no clue as to what I should personally monitor and manage myself.

I come from a C# background. Memory management in C# (technically, .NET) is entirely handled by the framework garbage collector. I understand that ARC is actually a compiler feature that automatically adds boiler-plate code where it belongs. Furthermore, my attempts to try and discover where I should manage my own releasing of objects has caused nothing but compiler errors because ARC wants to take care of it for me.

I have yet to find a case where I've needed to manage my objects. I am becoming "lazy" because I don't know what to monitor and release myself and I am completely oblivious about how this behavior could affect the performance of my application.

In new-user terms, what "gotchas" should I be aware of while using ARC in my iOS projects? I've read a few questions regarding memory management and ARC around here but, to be honest, they are not to friendly to the new iOS developer. Could someone please give a reasonable, bullet-point list that explains what problems and issues to watch out for, as well as a fair guide as to when self-management of memory is necessary?

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
RLH
  • 15,230
  • 22
  • 98
  • 182
  • 2
    If you're new, use ARC. For the average app, there are no performance gotchas. If your app uses a lot of memory (very large images, lots of sound files, etc) then you will need to deal with that, it's not to do with ARC, but just the maximum amount of memory you can use. – nycynik Jan 30 '12 at 22:17
  • You can still create reference cycles – Frederick Cheung Jan 30 '12 at 22:20
  • 2
    I disagree with the "not constructive" close reason here. This is a specific question with an objective answer, and it acts as a counterpart to the more technical [What kind of leaks does Objective-C's automatic reference counting (in Xcode 4.2) not prevent/minimize?](http://stackoverflow.com/questions/6260256/what-kind-of-leaks-does-objective-cs-automatic-reference-counting-in-xcode-4-2). This is not soliciting opinions or polling for an open-ended list of material that can't be contained within one answer. – Brad Larson Feb 01 '12 at 00:07
  • Thank you, Brad. Yes, I had even read that article and it was part of the reason why I asked the question. I still felt like I needed further clarity and greater sense of memory management in context of Cocoa/iOS/Objective-c/Xcode development. – RLH Feb 01 '12 at 14:12

1 Answers1

13
  • Circular References. When objects are codependent, they will leak. You will need to mark some references as weak, and Instruments can help you locate these references. These leaks won't even show up as leaks because they hold strong references to each other.

  • Create Autorelease Pools @autorelease to keep autorelease pool sizes down where you create many autoreleased objects (directly or indirectly). Specifically, your program and programs you depend on will autorelease many objects (ARC or otherwise). An autoreleased object is one which will be released "in the future". Every Cocoa program expects an autorelease pool to exist on each thread. This is why you create a new pool when you create a new thread, and why you create one in main. The pools operate as a stack - you may push and pop pools. When a pool is destroyed it sends its deferred release message to every object it holds. This means that really large loops with many temporary allocations may result in many objects which are referenced only by the pool, and the pool may grow very large. For this reason, you drain manage pools directly in some cases to minimize the number of objects that are waiting to be released and deallocated.

  • Use proper bridging/casting. Sometimes you will need to manage lifetimes explicitly. ARC handles the obvious cases, but there are complex cases where you will need to manage lifetimes explicitly.

  • When using malloc'ed and new'ed allocations, as well as opaque types in 'Core' APIs. ARC only manages NSObject types. You still need to explicitly free, delete, and use correct ref counting for these allocations, types, and when interfacing with those APIs.

  • Always follow NS-API naming conventions, and avoid explicit memory management attributes where possible.

  • You'll obviously need MRC when you compile sources without ARC or GC. This is quite common when using/working with other libraries/code bodies. Of course, the compiler handles interactions correctly so your ARC program should not leak.

  • ARC handles most of what you will need if you use proper naming and written style, but there will be a few other corner cases. Fortunately, you can still run Leaks and Zombies to locate these issues if you don't realize them during development.

Community
  • 1
  • 1
justin
  • 104,054
  • 14
  • 179
  • 226
  • 2
    I'd suggest talking about "temporary" objects instead of "autoreleased" objects, since someone coming straight to ARC will probably have no idea what an autoreleased object even is. Technically, "temporary" != "autoreleased", but in most cases, the advice will be good either way. – BJ Homer Jan 30 '12 at 22:56
  • @BJHomer ok, thanks -- i tried to explain autorelease pools in a paragraph instead. thanks for pointing that out. – justin Jan 30 '12 at 23:21
  • Thank you for posting this. This is an excellent start and I very well may print this out to keep it handy. – RLH Jan 31 '12 at 14:28