One of the most exciting new things introduced at this years WWDC were the ARC (short for Automatic Reference Counting) extensions for Objective-C that Apple’s compiler team has added to the new version 3.0 of the Apple LLVM Compiler.
Interestingly, ARC is also one of the few non-keynote items that can be discussed publicly, because the LLVM Compiler is open source, and the ARC extensions have now been publicly documented and are available in the LLVM repository.
Before ARC, Objective-C provided two ways to handle object lifetime management. Traditionally, objects are reference counted, with that reference count being influenced by calls to retain or release. If An objects’s reference count reaches zero, it was deallocated. This system is complimented by the (in my opinion very slick) concept of Auto Release Pools, where objects can be added to the active auto release pool via a call to autorelease. Essentially, this allows methods to return “unonwned” objects that the called can rely on still being valid, without having to worry about whether to release them or not. (compare that to more traditional memory models, such as Delphi).
Personally, i always liked the retain/release/autorelease model of Objective-C; i found it easy to use and it IMHO it always felt Garbage-Collection-like.
Of course, Objective-C 2.0 also introduced real Garbage Collection for the Mac OS X platform, starting with Leopard.
I’m not a hater of Garbage Collection, but since all of the library code we write here at RemObjects is shared between Mac OS X and iOS (which never supported GC, most likely or performance reasons), i’ve never actually made the switch to using GC in my apps – not even in those code bases that were decidedly Mac only. For one thing, even my apps reuse a lot of code between Mac and iOS versions, where applicable; for another, i did not want to get into the habit of not using retain/release/autorelease and then end up forgetting them when i do write library code that goes into iOS. And, as i mentioned above, i’ve always liked the retain/release/autorelease, so i didn’t really mind.
Automatic Reference Counting, or ARC for short, is an amazing technology, in that it combines all the benefits of writing GC code (not having to worry about releasing or retaining objects) with all the benefits of non-GC code (deterministic release of objects, no overhead of the collector kicking in to free your memory).
How does it do that? Essentially, by making the compiler smart enough to write all the retain/release/autorelease calls for you. What you end up with is code that is simply stripped of these calls (and as such, looks much like what you’d write when expecting GC), but that generates binary that has all your retains and releases in place, as if you had written them manually (except that the compiler is actually a lot smarter than that, further optimizes, and can generate even more efficient code under the hood).
It sounds like magic, and it sure feels like that when seeing this in action, but trust me – i’ve since ported a couple of our smaller internal apps to ARC, and it works like a charm. I’ve also had a chance to talk to some of the engineers involved with ARC while i was at WWDC, asked them a lot of questions and pointed out convers, and got a lot of good answers that reassured me that ARC is build on a solid foundation and works reliably ;).
Data Abstract and ARC
The cool thing about ARC is that – because it essentially takes care of inserting retain and release for you – it can be enabled on a file-by-file basis, and ARC and non-ARC code can interact just fine. This means that you can use libraries such as RO and DA from ARC code, even without the libraries themselves being ARC.
Of course, RemObjects SDK has a bit of a special role here, as it generates code for you that becomes part of your own project. Now, we could require you to just manually disable ARC for those files, but that’d be lame, so i have spent some time in evenings at WWDC (aren’t you proud of me) to ARC-proof the RO API and the CodeGen. We used some code constructs that ARC didn’t like (passing ivars by reference, ARC had no way of telling how these would be retained), so we’ve updated the RO API used by RODL generated code to no longer use those, and to include defines to include or exclude the necessary calls to release/retain/autorelease. As a result, when you update your *_Intf.h and *_Intf.m files the next time, they will be compatible with ARC and non-ARC projects.
All of this is available in the new beta builds of RemObjects SDK for Xcode and Data Abstract for Xcode that we made available today. If you are a licensed user with an active subscription, you can go and download those builds of beta.remobjects.com today (I would classify this beta release as fairly stable and well tested, suitable for production use).
Now, of course we’d also love to move the RO and DA libraries themselves to be built under ARC. The thing is, that switch is pretty much an either-or deal, and once we switch RO/DA over to ARC, we’d need to let go of support for iOS 3 (and older) and Leopard (and older) operating systems. We’re not quite ready to do that, because we know many of our customers will want to keep supporting those versions of the platforms. Also, pretty much the only benefit of switching RO/DA to ARC would be that our development team can keep working on the code base with the benfits of ARC (that, and the potential for some slight speed improvements due to ARC’s better optimization). You as the user of the frameworks would see no difference whether RO/DA is compiled as ARC or not. So we’ll bite the bullet and keep writing those retain/release/autorelease calls a while loger for you.