Skip to content

Instantly share code, notes, and snippets.

@nicolas17
Last active June 8, 2025 18:49
Show Gist options
  • Save nicolas17/ca6c936b15b795504f3703faa2e252f3 to your computer and use it in GitHub Desktop.
Save nicolas17/ca6c936b15b795504f3703faa2e252f3 to your computer and use it in GitHub Desktop.
ARC autorelease return value optimization

Original source code, compiled with ARC:

-(NSString*)name {
    return self->name;
}
-(void)caller {
    self->thingName = [self->thing name];
}

Lion

-(NSString*)name {
    return objc_retainAutoreleaseReturnValue(self->name);
}
-(void)caller {
    self->thingName = objc_retainAutoreleasedReturnValue([self->thing name]);
}

objc_retainAutoreleaseReturnValue(x) simply calls objc_autoreleaseReturnValue(objc_retain(x)).

objc_autoreleaseReturnValue checks if the caller is optimized. If it is, stores the object pointer in TLS, and skips the autorelease; otherwise, calls autorelease.

objc_retainAutoreleasedReturnValuechecks if the object pointer is in TLS. If it is, clears TLS and skips the retain; otherwise, calls retain.

El Capitan

Same code:

-(NSString*)name {
    return objc_retainAutoreleaseReturnValue(self->name);
}
-(void)caller {
    self->thingName = objc_retainAutoreleasedReturnValue([self->thing name]);
}

objc_retainAutoreleaseReturnValue checks if the caller is optimized. If it is, stores 0 in TLS, and skips both the retain and autorelease; Otherwise, calls retain and autorelease.

objc_retainAutoreleasedReturnValue checks if the TLS value is a 1. It's not, so it calls retain, since the callee didn't retain.

What's the advantage? Previously the callee did one retain, now the caller does one retain. User code size is the same since the fused retain + autoreleaseRV operation was used in Lion too, it just didn't do any special optimization.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment