ARC is coming!

Disclaimer: The opinions expressed in this article do not necessarily reflect the opinions of my employer.

No seriously, ARC is coming!

In case you haven’t already heard, iOS 5 is introducing a new memory management paradigm called ARC. This is all very interesting to read about if you don’t do iOS development. I mean, like every day. Apparently, it’s different if you do, because I woke up this afternoon, and realized that in 2 weeks (no, I don’t have inside information. Go read the rumors, it’s not that far off), Apple is not just going to release iOS 5, they’re going to completely change how I think about writing apps.[1]

Memory management is hard. 25% of the bugs I fix are me implementing something not quite how the customer wanted it. The other 75%? Seriously, it’s me doing memory wrong. So naturally, where I work, we’ve developed all sorts of internal policies to prevent these errors from ever occurring. All IBOutlets should be declared (nonatomic, retain), never use ivars for reference counted objects, don’t use NSNotificationCenter with blocks, when assigning to properties always use “self.”, … and on and on. So what happens when iOS 5 drops? All these things become deprecated? A bad idea? No. They become worthless. As in, you can’t call [var retain] or [var autorelease], they generate compiler errors. What? Basically, we’ve spent all this time getting really really good at defensive programming with Objective C memory, and in two short weeks, all that knowledge will – overnight – be obsolete. We’ll upgrade all our projects to use ARC (which supports iOS 4, no so forced upgrades or alienating clients), and we’ll never think about retain/release again.[2]

Wait, what’s the big deal?

Still don’t get it? Raise your hand if you’re using Python 3. Thought so. You’re not using python 3. And the same thing is happening with Perl 6. You change everything around, and the community says, “Hey, wait a minute! We invested all this time and effort into the old system. You can’t just up and obsolete it!”[3]. But this is, in fact, what Apple is doing. And in all fairness, ARC is going to be much better. It’s going to make whole classes of bugs impossible, and it will probably drop our bug rate by something like 50%. It will be wonderful! But I’ve been programming for over 9 years now, and I’ve never seen this. The biggest upgrade I’ve followed was when PHP upgraded to 5.3. What happened? Namespaces. Oh, and anonymous functions. Yes, the change log is extensive, and seriously, I don’t mean to in any way devalue the hard work of the PHP dev team. I love 5.3, and it really annoys me that my web host doesn’t support it! But it’s just not that earth shattering. And more importantly, I never upgraded any of my code. Not a single line needed to be changed.

But Apple provides an auto ARC tool!

I’m aware of this, but I’m not complaining about having to change things. This isn’t about “all the work it’s going to take to switch to ARC” (because it’s really not that hard). It’s a mental shift – except that it’s more than that. It’s a mental jump. You can’t do that in the space of 5 minutes. You’re lucky to do that in a day. It amazes me that Apple has the influence to tell such a large community, “forget that, now we do it this way. Starting tomorrow.”, and lo and behold, that’s the way it’s done. I know it’s a simple idea, but I don’t believe it. I just can’t believe that Apple can completely change the whole memory management architecture overnight. No looking back.

This changes everything, again.



[1] Technically, not businessly.
[2] That’s actually not strictly true, because blocks can still get you into trouble, but it’s a different kind of trouble. After iOS 5 is released, I will never, for the rest of my life, think about release/retain patterns. That entire mental model will die.
[3] Unless you’re working on an experimental language like Haskell, but those people knew what they were getting into.

About Bion

I'm a software developer at Modo Payments, a mobile payment provider. When I'm not hacking away the office, you I'm usually at home hacking on something else. Or practicing Aikido. Anyway, I just post things here that Google couldn't help me with, so maybe it'll help you in the future. Since you're reading this, I guess it worked :)
This entry was posted in Technology and tagged , . Bookmark the permalink.

2 Responses to ARC is coming!

  1. Drew says:

    It’s a big step forward, sure, but I think it’s a bit exaggerated. I don’t want to go into too much detail with the NDA, so I’ll constrain my responses to the public spec at http://clang.llvm.org/docs/AutomaticReferenceCounting.html

    1) The old system erred on the side of over-releasing, but the new system errs on the side of over-retaining (since the default lifetime qualifier is strong, a.k.a. a retain operation). This is definitely the right error to make, since it errs on the side of leaks instead of crashes. However, you can crash on a retain cycle.

    2) Notifications, a class of bugs you call out explicitly in your blog, actually get worse under ARC. over 50% of our notification bugs are a failure to unregister for notifications, typically because the unregistration code we put in dealloc isn’t running, meaning the object isn’t getting dealloced (i.e. there’s a cycle preventing its deallocation). So cycles can in fact cause crashes, particularly when notifications get involved.

    3) Any time you enter C-land (such as the ABAddressBook APIs or any other toll-free bridged type), you have to guess the right briding qualifier so that the runtime knows how to manage the memory.

    4) Out-parameters (e.g. NSError**) are now nontrivial. The default implementation is that your implicitly strong NSError in the caller gets converted to the implicitly autoreleased NSError** in the called. That is, the parameter inside the function points to a different object than the function was called with. This is a safe optimization a lot of the time, but not with output parameters, which require additional magic not obvious to a C developer.

    5) Because every declaration is implicitly strong, assigning a block to an ivar will usually create a retain cycle now. Variables that are declared __block now implicitly retain when the block is declared, which is a second unusual retain cycle mechanism involving blocks.

    Yes, ARC is nifty and a really good idea. But ARC is to retain/release as cruise control is to accel/brake. It saves you a lot of effort, but in no way shape or form can you get by without knowing how the basics work. In places it gets *more* complicated, because you now have more to learn–but the overall effect is that the defaults are better, so you can get further with knowing less.

    • Bion says:

      I think you missed my point. The point isn’t that ARC is easier or harder, better or worse, but that it’s completely different. As you pointed out, it’s asking “where does this get released?” instead of “where was this retained?”. It’s looking for cycles instead of leaks.

      All of the points that you brought up are differences in how ARC works, and that’s the whole point. There is no [retain] [release] API anymore: everything changed.

Leave a Reply to Drew Cancel reply

Your email address will not be published. Required fields are marked *