On Mar 1, 2018, at 13:05:37, Quincey Morris <quinceymorris@...> wrote:
— This solution:
NSUInteger c = [self computeFor:42 reason:needReason ? &s : nil];
is AFAIK a bit dangerous. The “computeFor:reason:” method stores an *autoreleased* string pointer into its output parameter, so “s” will end up containing this autoreleased pointer when “needReason” is true. That autoreleased pointer is a ticking time bomb that will explode if it’s still being used somewhere when its autorelease pool is drained (which could be a *lot* later, leading to hard-to-find bug) without being owned somewhere else. Whether this is a problem depends on what you do with “s” next.
I disagree that it's dangerous. It's the standard way code is written when a parameter is passed back by reference. How many times in Apple code do you see something like:
NSError* err;
if([thing doStuffAndReturnError:&err])
;
else
; // Handle error.
They don't add any decoration to the local variable err. And every time you autocomplete a method body that includes a reference param, Xcode includes __autoreleasing between the splats:
-(BOOL) doStuffAndReturnError:(NSError*__autoreleasing*)err;
They even say this in the "Transitioning to ARC Release Notes":
• __autoreleasing is used to denote arguments that are passed by reference (id *) and are autoreleased on return.
Then goes on to explain how the compiler takes care of things by rewriting it for you.
--
Steve Mills
Drummer, Mac geek