我在试着理解在ARC中从CFStringRef
中获得NSString
分的正确方法?
在不造成内存泄漏的情况下,正确的方法是什么?
我在试着理解在ARC中从CFStringRef
中获得NSString
分的正确方法?
在不造成内存泄漏的情况下,正确的方法是什么?
典型的
NSString *yourFriendlyNSString = (__bridge NSString *)yourFriendlyCFString;
和
CFStringRef yourFriendlyCFString = (__bridge CFStringRef)yourFriendlyNSString;
现在,如果你想知道为什么有__bridge
关键字,你可以参考Apple documentation.你会发现:
__bridge
transfers a pointer between Objective-C 和 Core Foundation with no transfer of ownership.
__bridge_retained
orCFBridgingRetain
casts an Objective-C pointer to a Core Foundation pointer 和 also transfers ownership to you. You are responsible for calling CFRelease or a related function to relinquish ownership of the object.
__bridge_transfer
orCFBridgingRelease
moves a non-Objective-C pointer to Objective-C 和 also transfers ownership to ARC. ARC is responsible for relinquishing ownership of the object.
Which means that in the above cases you are casting the object without changing the ownership. This implies that in neither case you will be in charge of h和ling the memory of the strings.
在某些情况下,您可能出于某种原因想要转让所有权.
例如,考虑下面的片段
- (void)sayHi {
CFStringRef str = CFStringCreateWithCString(NULL, "Hello World!", kCFStringEncodingMacRoman);
NSString * aNSString = (__bridge NSString *)str;
NSLog(@"%@", aNSString);
CFRelease(str); //you have to release the string because you created it with a 'Create' CF function
}
在这种情况下,你可能想通过在铸造时转移所有权来节省CFRelease
英镑.
- (void)sayHi {
CFStringRef str = CFStringCreateWithCString(NULL, "Hello World!", kCFStringEncodingMacRoman);
NSString * aNSString = (__bridge_transfer NSString *)str;
// or alternatively
NSString * aNSString = (NSString *)CFBridgingRelease(str);
NSLog(@"%@", aNSString);
}
The ownership of str
has been transferred, so now ARC will kick in 和 release the memory for you.
On the other way around you can cast a NSString *
to a CFString
using a __bridge_retained
cast, so that you will own the object 和 you'll have to explicitly release it by using CFRelease
.
总而言之,你可以
// Don't transfer ownership. You won't have to call `CFRelease`
CFStringRef str = (__bridge CFStringRef)string;
// Transfer ownership (i.e. get ARC out of the way). The object is now yours 和 you must call `CFRelease` when you're done with it
CFStringRef str = (__bridge_retained CFStringRef)string // you will have to call `CFRelease`
// Don't transfer ownership. ARC stays out of the way, 和 you must call `CFRelease` on `str` if appropriate (depending on how the `CFString` was created)
NSString *string = (__bridge NSString *)str;
// Transfer ownership to ARC. ARC kicks in 和 it's now in charge of releasing the string object. You won't have to explicitly call `CFRelease` on `str`
NSString *string = (__bridge_transfer NSString *)str;