I am using ARC, and have confusion while using __bridge_transfer
. I have a property userName
as following:
@property (nonatomic, re
Case 1 and case 2 are equivalent. Think of it like this:
Case 1:
-(void)func {
NSString *name = someObject; // Retain, so +1 on the reference count
self.userName = name; // Retain, so +1 on the reference count
// End of function, name is going out of scope,
// so release name, so -1 on the reference count.
// Total change to the reference count: +1 for self.userName.
}
Case 2:
-(void)func {
self.userName = someObject; // Retain, so +1 on the reference count
// End of function.
// Total change to the reference count: +1 for self.userName.
}
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 (a CFStringRef
). The Copy
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
:
self.userName = (__bridge_transfer NSString *)ABRecordCopyCompositeName(person); // +1 inside ABRecordCopyCompositeName, +1 for self.userName, -1 at the end, because of the __bridge_transfer.
// self.userName now is the only strong reference. Good.
With __bridge
:
CFStringRef userName = ABRecordCopyCompositeName(person); // +1 inside ABRecordCopyCompositeName.
self.userName = (__bridge NSString *)userName; // +1 for self.userName, ARC does nothing because of the __bridge.
CFRelease(userName); // -1.
// self.userName now is the only strong reference. Good.
With __bridge
and a memory leak:
self.userName = (__bridge NSString *)ABRecordCopyCompositeName(person); // +1 inside ABRecordCopyCompositeName, +1 for self.userName, ARC does nothing because of the __bridge.
// self.userName now is one strong reference, but reference count is 2.
// Memory leak.