-
-
Save nicklockwood/1563325 to your computer and use it in GitHub Desktop.
// | |
// 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: | |
// | |
// https://gist.github.com/1563325 | |
// | |
#import <Availability.h> | |
#undef ah_retain | |
#undef ah_dealloc | |
#undef ah_autorelease autorelease | |
#undef ah_dealloc dealloc | |
#if __has_feature(objc_arc) | |
#define ah_retain self | |
#define ah_release self | |
#define ah_autorelease self | |
#define ah_dealloc self | |
#else | |
#define ah_retain retain | |
#define ah_release release | |
#define ah_autorelease autorelease | |
#define ah_dealloc dealloc | |
#undef __bridge | |
#define __bridge | |
#undef __bridge_transfer | |
#define __bridge_transfer | |
#endif | |
// Weak reference support | |
#import <Availability.h> | |
#if !__has_feature(objc_arc_weak) | |
#undef ah_weak | |
#define ah_weak unsafe_unretained | |
#undef __ah_weak | |
#define __ah_weak __unsafe_unretained | |
#endif | |
// Weak delegate support | |
#import <Availability.h> | |
#undef ah_weak_delegate | |
#undef __ah_weak_delegate | |
#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 | |
#else | |
#define ah_weak_delegate unsafe_unretained | |
#define __ah_weak_delegate __unsafe_unretained | |
#endif | |
// ARC Helper ends |
License
ARC Helper
Version 2.1, June 24th, 2012
Copyright (C) 2012 Charcoal Design
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
- The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required. - Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software. - This notice may not be removed or altered from any source distribution.
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:
#define AH_AUTORELEASE(x) [(x) autorelease]
Fix here: https://gist.github.com/1878186.
Thanks! I like your solution, and it shouldn't cause any problems with version compatibility. I've updated the gist with your fix.
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:
In ARC:
define AH_IB_OUTLET AH_WEAK
Non-ARC:
define AH_IB_OUTLET AH_STRONG
I don't think there's a problem with using strong outlets in ARC code, as long as you nil them out in your viewDidUnload methods as before.
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.
Hi,
We wrote another gist for ARC support. Our ARCMacro.h is very simple and natural to use.
Nice. I've updated ARCHelper to use a similar approach.
Nice. You can add this too:
#define __bridge_transfer
on my fork, I have changed "release" to "ah_release" in order to be compatible with structs CFDictionaryKeyCallBacks and CFDictionaryValueCallBack from CoreFoundation file CFDictionary.h
IMO it is a bad gist, it breaks Convert to Objective-C ARC...
tool by hiding release
, autorelease
and retain
calls behind self
.
Moreover it reduces performance because you will call self
under ARC instead of simply removing calls. Then ARC will add his own release
calls instead of using yours.
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.
@nverinaud you're right, but I changed it to use the ah prefix for everything some time ago (before your comment), so that criticism is no longer applicable.
The performance thing is basically a non-issue.
@nverinaud you may prefer this older version if you are worried about performance:
https://gist.github.com/nicklockwood/1563325/4d32686a6058cb9bc409767ee7cc37a7993cb2df
Xcode gave me "Extra tokens at end of #undef directive" warning message.
#undef ah_autorelease autorelease
#undef ah_dealloc dealloc
Release Notes
Version 2.2
Version 2.1
Version 2.0
Version 1.3.1
<Availability.h>
import to weak reference module in case it isn't included in the prefix.pch fileVersion 1.3
Version 1.2.2
Version 1.2.1
Version 1.2
Version 1.1
Version 1.0