Under manual memory management, I use this pattern fairly often:
NSString * myStr = /* some local object */
[UIView beginAnimation:@"foo" context:(void *)[myStr retain]];
And then, later and asynchronously:
- (void)animationDidStop:(NSString *)anim finished:(NSNumber *)num context:(void *)context
{
NSString * contextStr = (NSString *)context;
// ...
[contextStr release];
}
i.e. I manually managed the lifetime of an object used as an opaque context. (This is true for the old UIView animations but also for other kinds of API that I use.)
Under ARC, my instinct is that I want to __bridge_retained going in and __bridge_transfer in the handler, as suggested here. But this treats a Cocoa object as a CFType not because it’s really bridged, but just for the purpose of shoving a retain down its throat.
Is this valid, and is this stylistically acceptable? If not, what’s the better* solution?
(The accepted answer in this question gives a different answer, saying that __bridge alone is OK, but that seems to me to be wrong, since the original string would be at risk of being deallocated as soon as it goes out of scope in the first function. Right?)
*Please don’t say “use block-based animations instead”. (That’s not what I’m asking about.)
Go with your instinct.
__bridge_retainedtransfers management of an object to you from ARC, while__bridge_transferdoes the reverse, don’t worry about treating the object as aCFType– you’re not really doing that just taking over management.The other approach you see recommended is to construct your code so that ARC retains management, but this can easily come across as contrived (and get messy). Having the API you’re using maintain the value as it is designed to do is clean; just comment the code appropriately where management is handed to the API and returned back to ARC.