我想了解NSString
从CFStringRef
ARC 中获取 a 的正确方法?反方向也一样,CFStringRef
在NSString
ARC 中?
在不造成内存泄漏的情况下执行此操作的正确方法是什么?
我想了解NSString
从CFStringRef
ARC 中获取 a 的正确方法?反方向也一样,CFStringRef
在NSString
ARC 中?
在不造成内存泄漏的情况下执行此操作的正确方法是什么?
通常
NSString *yourFriendlyNSString = (__bridge NSString *)yourFriendlyCFString;
和
CFStringRef yourFriendlyCFString = (__bridge CFStringRef)yourFriendlyNSString;
现在,如果您想知道__bridge
关键字为何存在,可以参考Apple 文档。在那里你会发现:
__bridge
在没有所有权转移的情况下在 Objective-C 和 Core Foundation 之间转移一个指针。
__bridge_retained
或CFBridgingRetain
将 Objective-C 指针转换为 Core Foundation 指针,并将所有权转移给您。您负责调用 CFRelease 或相关函数来放弃对象的所有权。
__bridge_transfer
或CFBridgingRelease
将非 Objective-C 指针移动到 Objective-C 并将所有权转移给 ARC。ARC 负责放弃对象的所有权。
这意味着在上述情况下,您正在转换对象而不更改所有权。这意味着在这两种情况下,您都将负责处理字符串的内存。
也可能存在出于某种原因您想要转让所有权的情况。
例如考虑以下片段
- (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
通过在投射时转移所有权来保存 a。
- (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 将为您启动并释放内存。
另一方面,您可以使用强制转换将 a强制NSString *
转换为a ,这样您将拥有该对象,并且您必须通过 using 显式释放它。CFString
__bridge_retained
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 and 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, 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;