|// ARC Helper|
|// Version 2.2|
|// Created by Nick Lockwood on 05/01/2012.|
|// Copyright 2012 Charcoal Design|
|// Distributed under the permissive zlib license|
|// Get the latest version from here:|
|#undef ah_autorelease autorelease|
|#undef ah_dealloc dealloc|
|#define ah_retain self|
|#define ah_release self|
|#define ah_autorelease self|
|#define ah_dealloc self|
|#define ah_retain retain|
|#define ah_release release|
|#define ah_autorelease autorelease|
|#define ah_dealloc dealloc|
|// Weak reference support|
|#define ah_weak unsafe_unretained|
|#define __ah_weak __unsafe_unretained|
|// Weak delegate support|
|#if __has_feature(objc_arc_weak) && \|
|(!(defined __MAC_OS_X_VERSION_MIN_REQUIRED) || \|
|__MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_8)|
|#define ah_weak_delegate weak|
|#define __ah_weak_delegate __weak|
|#define ah_weak_delegate unsafe_unretained|
|#define __ah_weak_delegate __unsafe_unretained|
|// ARC Helper ends|
ARC Helper is an Objective-C snippet that can be either pasted into the header of a file or used as a header file in its own right. It is designed to solve the problem of writing library code that can be used with both ARC and non-ARC projects without needing to be modified. It is designed to work with both Mac OS and iOS projects.
ARC Helper is modular. For projects that are designed to work only with ARC enabled, you can use just the second and/or 3rd modules on their own (the part from "Weak reference support" down) and omit the first block. For projects that are iOS only, you don't need the 3rd module (the part from "Weak delegate support" down), which deals with weak references to classes such as NSWindowController on Mac OS that do not support weak references under Mac OS 10.7.
Supported OS & SDK Versions
NOTE: 'Supported' means that the library has been tested with this version. 'Compatible' means that the library should work on this iOS version (i.e. it doesn't rely on any unavailable SDK features) but is no longer being tested for compatibility and may require tweaking or bug fixes to run correctly.
For a single-class library, the easiest way to use ARC Helper is to paste the code into the top of your .h file.
For a multi-class library, you may prefer to save the ARC Helper snippet as a header file (suggested name is ARCHelper.h) and import it into any classes that use it.
Note that the ARC Helper code can safely be included multiple times in a project, so you need not worry about duplicating it in multiple files, although issues may arise if your project includes multiple incompatible versions of the ARC Helper code.
ARC Helper consists of a set of macros that are designed to be used in place of the standard Objective-C memory management functions and macros. These macros will generate code appropriate to the build target.
On the rare occasions (such as a dealloc block) where you wish to eliminate several lines or a whole method or under ARC, you can use the
When running under ARC, ARCHelper replaces these methods with macros that do nothing. You can therefore use
Use this instead of
Use this instead of
This is used when casting between C-style pointers and NSObject references, e.g.
The ah_weak reference type should be used for defining weak/unretained object properties, e.g.
Similar to to the
Annoyingly, on Mac OS 10.7 a number of classes including NSWindowController and NSViewController do not support weak references. When creating a user interface component library that uses the delegate pattern to communicate with a controller, you would naturally want to use a weak reference for the delegate, but it's not safe to use weak references for this on Mac OS, even when targeting 10.7 and above. The
Version 2.1, June 24th, 2012
Copyright (C) 2012 Charcoal Design
This software is provided 'as-is', without any express or implied
Permission is granted to anyone to use this software for any purpose,
Hey great gist, but as-written it eats compiler errors. I forgot a bracket within an AH_AUTORELEASE call and it took forever to hunt down. Parameters just need to be wrapped in parentheses like so:
Fix here: https://gist.github.com/1878186.
Great idea Nick - thank you.
One thing that I also found I needed was some mechanism to specify the property type for IBOutlets. In ARC flavour, they should be declared as weak properties, while in non-ARC they are retained.
I added a new define:
define AH_IB_OUTLET AH_WEAK
define AH_IB_OUTLET AH_STRONG
Fair enough - it is what Apple recommends, but you're probably right in that it will work either way.
I've got some code that is incoming by a developer who went straight to ARC and as such I'm not that that he's actually done the nil'ing out in viewDidUnload.
Thanks again Nick - it's a handy little wrapper.
If you need code to work in a non-ARC environment (or on iOS4, which doesn't support true weak references, only unsafe unretained references), you'll need to add the nils in viewDidUnload anyway, so you may as well use strong outlets. If you don't need it to work in a non-ARC environment, you don't need to use this gist anyway.
As for forgetting to nil strong outlets in your viewDidUnload, it's not the end of the world. It won't crash and it won't leak, it just means that offscreen views use up a bit more memory because they don't free their subviews. On the other hand, if you forget to nil out an unsafe unretained outlet and you try to access it, you'll crash, which is a good argument for using strong outlets (bigger memory footprint is preferable to random crashes).
So in conclusion, if you are supporting iOS4 and up, stick with strong outlets, and if you are supporting iOS5 and up, use ARC and weak outlets, but don't bother using this gist.
IMO it is a bad gist, it breaks
Moreover it reduces performance because you will call
I suggest wrap your non-ARC code around preprocessor directives like in this file: https://github.com/nverinaud/NVUIGradientButton/blob/master/lib/NVUIGradientButton/NVUIGradientButton.m.