I am using ARC, and have confusion while using __bridge_transfer
. I have a property userName
as following:
@property (nonatomic, retain) NSString *userName;
...
@synthesize userName = _userName;
...
CASE 1:
NSString *name = (__bridge_transfer NSString *)ABRecordCopyCompositeName(person);
self.userName = name;
CASE 2:
self.userName = (__bridge_transfer NSString *)ABRecordCopyCompositeName(person);
where person
is of type ABRecordRef
.
In CASE 1, ARC would release local variable name (as per my understanding, correct me if I am wrong), however what would happen in CASE 2 ? Should I use __bridge
in CASE 2 OR CASE 2 should not be used at all ? in CASE 2 with __bridge_transfer
or __bridge
, how to balance the reference count ?
in CASE 2, with __bridge_transfer
, will ARC release the object (the object, which is being passed as an argument to the setter (void)setUserName:(NSString *)userName
)?
Precisely because this is confusing, I recommend that you use
CFBridgingRelease()
andCFBridgingRetain()
rather than casts with__bridge_transfer
and__bridge_retained
, respectively. Then, the only "unusual" cast you need to remember is__bridge
, which does nothing with ownership.I find it easier to remember because, with something like
ABRecordCopyCompositeName()
which leaves you with the responsibility toCFRelease()
the returned object, you can useCFBridgingRelease()
to discharge that responsibility and the analogy is obvious.Similarly, you'd only use
CFBridgingRetain()
in a context where you would useCFRetain()
if the object pointer were already a Core Foundation type.So, your code could be:
Or:
In both cases, the
CFBridgingRelease()
balances theCopy
in the function name that implies that you have a responsibility to release the object. After that, it's all somebody else's responsibility. ARC manages thename
variable. The implementer of the setter for theuserName
property manages that. (It happens to be ARC in this case, too, but that's irrelevant.)Case 1 and case 2 are equivalent. Think of it like this:
Case 1:
Case 2:
So they work out the same. Note that the compiler is allowed to cancel out a retain and release pair, if it is safe to do so. In a simple case like this it would certainly elide them. Thinking about it with all the +1 and -1 changes to the reference count is just to make it clearer.
To answer the bit about __bridge versus __bridge_transfer: you have called
ABRecordCopyCompositeName
, which returns a reference to an unmanaged object (aCFStringRef
). TheCopy
in the function name tells you that this object is now owned by you, and you need to release it eventually.You can either do this by calling
CFRelease
, or you can ask ARC to do it for you.__bridge
tells ARC that it is not allowed to take ownership (in other words, you want to release the object manually, or it isn't owned by you).__bridge_transfer
tells ARC that it should take ownership and release the object at the end of the full expression (in other words, you are asking ARC to do the release for you).With
__bridge_transfer
:With
__bridge
:With
__bridge
and a memory leak:When you call
ABRecordCopyCompositeName()
, someone must release the returned object at some point. Using__bridge_transfer
ensures that ARC will release the object for you. Without__bridge_transfer
, you must release the returned object manually. Those are the only two options.Therefore, you must use
__bridge_transfer
in both cases.A nice exercise is to induce a leak by using
__bridge
instead of__bridge_transfer
, then use Xcode and Instruments to try and find the leak. Does the compiler pick up the leak? Does static analysis (Project -> Analyze) pick up the leak? Does Instruments pick up the leak? If so, you'll then know how to check whether__bridge_transfer
solves the problem.