Skip to content

Supporting both ARC and MRC build settings

Let’s face it, people don’t read `README`s. If you write library code that people are going to use in their own projects, you can’t rely on that bit at the bottom of the documentation that tells people to do -fobjc-arc on your files that they drop into your project. You can rely on all the issues that get reported about memory leaks :-).

The actual solution

Your project should build a library (static by necessity on iPhone, there are other options on the Mac) so developers can just add that one library target as a build dependency, and drop the headers into their own projects.

The result is that now your memory management is hidden behind the object boundary and the naming conventions of your methods. You should probably still be using manual reference counting if you want people who’ve already written apps to be able to link against your code without problems, because there are still apps out there that target versions of iOS that can’t link ARCified objects. Regardless, whether an app is ARCified or not it will be able to link your library.

The other solution

Sometimes you find code that developers are supposed to integrate by dropping the source files into their targets. This is worse than providing a static library: now you’ve made the developer care about the internals of your code – the compiler flags you need to set become something they have to deal with in their target’s build settings. This includes the setting for whether automatic reference counting is enabled.

…unless you support both possibilities. I’ve used the macros defined below to use the same code with both automatic and manual reference counting compiler settings. This code included Core Foundation bridged objects, so this isn’t just “the trivial case” (whatever that is).

#if __has_feature(objc_arc)
# define FZARelease(obj)
# define FZAAutorelease(obj) (obj)
# define FZARetain(obj) (obj)
#else
# define FZARelease(obj) [(obj) release]
# define FZAAutorelease(obj) [(obj) autorelease]
# define FZARetain(obj) [(obj) retain]
#endif

Objective-C garbage collection

I haven’t had a need to test how that interacts with garbage collection, or build code that works in all three environments. However, if you already wrote your code to support (rather than require) GC, and you don’t rely on CFMakeCollectable, this collection of macros at least won’t make anything worse.

{ 2 } Comments

  1. Saul Mora | June 10, 2012 at 7:17 am | Permalink

    I used to use something similar in the early days of ARC. While some may still consider these early days, It still seems that this approach fights the provided tools. This is why I eventually removed it all from MagicalRecord, and went ARC only from here on in. ARC may not be perfect, but it’s pretty good, and these macros seem to just maintain cruft in your code longer …

  2. Graham | June 10, 2012 at 6:50 pm | Permalink

    I agree that this is just cruft, which in my case was born of expedience. There are still a number of products around that don’t work with ARC. My preference would be for a manually-reference-counted library product.