In an ideal World, we would all be using ARC now and all our code bases would have been converted to ARC but, if like me, you still have some legacy code you may find yourself needed to make some code work both with and without ARC.
I wrote the following macros to make converting old non-ARC code to ARC-agnostic code. It’s by no means an exhaustive set, but it may save you some time if you find yourself needing to do the same thing.
Update: In the first posting of this code the ARC versions of retain and autorelease were incorrect. User sophtwhere was kind enough to send solutions to the problem.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#if ! __has_feature(objc_arc) #define IDZ_RETAIN(_o) [(_o) retain] #define IDZ_RELEASE(_o) [(_o) release] #define IDZ_AUTORELEASE(_o) [(_o) autorelease] #define IDZ_SUPER_DEALLOC [super dealloc] #define IDZ_BRIDGE_CAST(_type, _identifier) ((_type)(_identifier)) #else #define IDZ_RETAIN(_o) (_o) #define IDZ_RELEASE(_o) #define IDZ_AUTORELEASE(_o) (_o) #define IDZ_SUPER_DEALLOC #define IDZ_BRIDGE_CAST(_type, _identifier) ((__bridge _type)(_identifier)) #endif |
not sure how you code objective c, but those macros won’t work in some situations.
consider the case of
return [anObject autorelease];
this would mean that “return IDZ_AUTORELEASE(anObject);” evaluates to
Non ARC (correct)
return [anObject autorelease];
ARC (incorrect)
return ;
or the case of
NSString *myString = [passedInParam retain];
this would mean that “NSString *myString =IDZ_RETAIN(passedInParam);” evaluates to
Non ARC (correct)
NSString *myString = [passedInParam retain];
ARC (incorrect)
NSString *myString = ;
it think you’d need to change it to:
#if ! __has_feature(objc_arc)
#define IDZ_RETAIN(_o) [(_o) retain]
#define IDZ_RELEASE(_o) [(_o) release]
#define IDZ_AUTORELEASE(_o) [(_o) autorelease]
#define IDZ_SUPER_DEALLOC [super dealloc]
#define IDZ_BRIDGE_CAST(_type, _identifier) ((_type)(_identifier))
#else
#define IDZ_RETAIN(_o) _o
#define IDZ_RELEASE(_o)
#define IDZ_AUTORELEASE(_o) _o
#define IDZ_SUPER_DEALLOC
#define IDZ_BRIDGE_CAST(_type, _identifier) ((__bridge _type)(_identifier))
#endif
You are absolutely correct. I came across the same problem in my own code and forgot to come back and fix it here. Thank you so much for posting the solution.
i spent a few hours playing around with your concept and came up with slightly different version of my own.
basically you add include 2 files in your project:
NSObject+arcAgnostics.h
NSObject+arcAgnostics.m
and ensure that the NSObject+arcAgnostics.m file is compiled with -fno-objc-arc
any files you want to make arc agnostic (for example “myfile.m” , import the NSObject+arcAgnostics.h file into myfile.m (definitely do not import NSObject+arcAgnostics.h into any other .h file!)
in an ideal world, all you need to do is change any
[super dealloc];
calls to read[SUPER_DEALLOC];
everything else is handled by some tricky macro cut and pasting.
enjoy.
sorry, the link embedding code did not work..
here are the 2 files on pastebin
http://pastebin.com/nhxDy4QQ – NSObject+arcAgnostics.h
http://pastebin.com/wVVSCWvy – NSObject+arcAgnostics.m