NSString到CFStringRef和CFStringRef到ARC中的NSString?
我想了解从ARC中的CFStringRef
获取NSString
的正确方法? 相反的方向, CFStringRef
到ARC的NSString
?
什么是正确的方法来做到这一点,而不造成内存泄漏?
通常
NSString *yourFriendlyNSString = (__bridge NSString *)yourFriendlyCFString;
和
CFStringRef yourFriendlyCFString = (__bridge CFStringRef)yourFriendlyNSString;
现在,如果你想知道为什么__bridge
关键字在那里,你可以参考苹果文档 。 在那里你会发现:
__bridge
在Objective-C和Core Foundation之间传递一个指针,但不转让所有权。
__bridge_retained
或CFBridgingRetain
将一个Objective-C指针转换为Core Foundation指针,并将所有权转让给您。 您有责任调用CFRelease或相关函数来放弃对象的所有权。
__bridge_transfer
或CFBridgingRelease
将非Objective-C指针移动到Objective-C,并将所有权转移给ARC。 ARC负责放弃对象的所有权。
这意味着在上述情况下,您正在投射对象而不更改所有权。 这意味着,在任何情况下,你都将负责处理string的记忆。
出于某种原因,您可能还会出现您想转让所有权的情况。
例如考虑下面的代码片段
- (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); }
str
的所有权已经转移,所以现在ARC将会启动并释放你的内存。
另一方面,您可以使用__bridge_retained
将NSString *
CFString
为__bridge_retained
,以便拥有该对象,并且必须使用CFRelease
显式释放该对象。
把它包起来,你可以拥有
NSString→CFString
// Don't transfer ownership. You won't have to call `CFRelease` CFStringRef str = (__bridge CFStringRef)string; // Transfer ownership (ie get ARC out of the way). The object is now yours and you must call `CFRelease` when you're done with it CFStringRef str = (__bridge_retained CFStringRef)string // you will have to call `CFRelease`
CFString→NSString
// Don't transfer ownership. ARC stays out of the way, and 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 and 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;