1. Why ARC does not handle CFRefType?
CFRefType basically is a "void *" type, it point to a core foundation object that handles CFRelease and CFRetain, but not retain and release as objective-c object does. So CFRefType is not managed by ARC. That is why when casting between Objective-c type and CFRefType, you need to tell ARC who owns the object.
2. Ownership transfer for Objective C property and variable for ARC
When assigning values to objective c property or variable, it implies the ownership transferring, the receiver either become the owner of the assigned object or not depending on the variable qualifier:
__strong: the receiver becomes the new owner. (default)
__weak: the receiver is not the owner, and the object may become nil anytime
__unsafe_unretained: the receive is not the owner, and not set to nil if the object is deleted.
__autoreleasing: the receiver is retained and autoreleased. is usually used for declaring by reference parameter, it should always used within an autorelease. Most of time, the arced object is released when the variable is set to nil or the variable is out of definition scope. __autoleasing will allow to collect an object when the thread ends or the autorelease pool close, so it uses thread instead of variable scope to control the object's life time.
3. CFRefType ownership transfer
If a method contains copy or create and return a CFRefType object, then it transfers the ownership to caller, and caller needs to CFRelease it.
4. Objective C ownership transfer
CFRefType basically is a "void *" type, it point to a core foundation object that handles CFRelease and CFRetain, but not retain and release as objective-c object does. So CFRefType is not managed by ARC. That is why when casting between Objective-c type and CFRefType, you need to tell ARC who owns the object.
__bridge: no ownership transfer
NSMutableString * string1 = [[NSMutableString alloc] initWithFormat:@"First : %@", @"adb"];
CFStringRef cfString = nil;
cfString = (__bridge CFStringRef )string1;
string1 = nil; //at this moment, cfString is also set to nil
__bridge_retained
or CFBridgingRetain: transfer
ownershjp of Objective-C object to Core Foundation pointer, and need to call CFRelease
to collect the object
NSMutableString * string1 = nil;
CFStringRef cfString = nil;
string1 = [[NSMutableString alloc] initWithFormat:@"First Name: %@", @"adb"];
cfString = (__bridge_retained CFStringRef )string1;
string1 = nil; //at this moment, cfString is still hold the original string, as it has been retained
__bridge_transfer
or CFBridgingRelease: transfer ownership of core foundation object to ARC, ARC will release the object when it is no longer referenced
NSMutableString * string1 = nil;
CFStringRef cfString = CFSTR("Hello, world.");;
string1 = (__bridge_transfer NSMutableString*)cfString;
CFRelease(cfString); //at this moment string1 still hold the valid string data
When assigning values to objective c property or variable, it implies the ownership transferring, the receiver either become the owner of the assigned object or not depending on the variable qualifier:
__strong: the receiver becomes the new owner. (default)
__weak: the receiver is not the owner, and the object may become nil anytime
__unsafe_unretained: the receive is not the owner, and not set to nil if the object is deleted.
__autoreleasing: the receiver is retained and autoreleased. is usually used for declaring by reference parameter, it should always used within an autorelease. Most of time, the arced object is released when the variable is set to nil or the variable is out of definition scope. __autoleasing will allow to collect an object when the thread ends or the autorelease pool close, so it uses thread instead of variable scope to control the object's life time.
3. CFRefType ownership transfer
If a method contains copy or create and return a CFRefType object, then it transfers the ownership to caller, and caller needs to CFRelease it.
4. Objective C ownership transfer
If the object transfer the ownership to caller and needs ARC to release the object, then the method needs to start with alloc, copy, mutableCopy or new. Otherwise, ARC will not collect it when it is no longer referred.
5. id and void*
id represents an Objective C object, which responds to retain and release method, while void * is just an memory blob. A lot of objective C API accepts id as parameter, but not void*, so void* cannot be cast as id.
5. id and void*
id represents an Objective C object, which responds to retain and release method, while void * is just an memory blob. A lot of objective C API accepts id as parameter, but not void*, so void* cannot be cast as id.
No comments:
Post a Comment