Is it better (faster & more efficient) to use alloc
or autorelease
initializers. E.g.:
- (NSString *)hello:(NSString *)name {
return [[NSString alloc] initWithFormat:@"Hello, %@", name];
}
OR
- (NSString *)hello:(NSString *)name {
return [NSString stringWithFormat:@"Hello, %@", name];
// return [@"Hello, " stringByAppendingString:name]; // even simpler
}
I know that in most cases, performance here shouldn't matter. But, I'd still like to get in the habit of doing it the better way.
If they do exactly the same thing, then I prefer the latter option because it's shorter to type and more readable.
In Xcode 4.2, is there a way to see what ARC compiles to, i.e., where it puts retain
, release
, autorelease
, etc? This feature would be very useful while switching over to ARC. I know you shouldn't have to think about this stuff, but it'd help me figure out the answer to questions like these.
Best Answer
The difference is subtle, but you should opt for the
autorelease
versions. Firstly, your code is much more readable. Secondly, on inspection of the optimized assembly output, theautorelease
version is slightly more optimal.The
autorelease
version,translates to
Whereas the [[alloc] init] version looks like the following:
As expected, it is a little longer, because it is calling the
alloc
andinitWithFormat:
methods. What is particularly interesting is ARC is generating sub-optimal code here, as it retains thename
string (noted by call to _objc_retain) and later released after the call toinitWithFormat:
.If we add the
__unsafe_unretained
ownership qualifier, as in the following example, the code is rendered optimally.__unsafe_unretained
indicates to the compiler to use primitive (copy pointer) assignment semantics.as follows: