Re: string pointer


Steve Mills
 

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

Join cocoa@apple-dev.groups.io to automatically receive all group messages.