我在试着理解在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 or CFBridgingRetain 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 or CFBridgingRelease 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.


总而言之,你可以

NSString → CFString

// 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`

CFString → NSString

// 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;

Objective-c相关问答推荐

Apple Silicon 上的 dispatch_time 计算失败

如何限制 UITextField 中的特殊字符(点和下划线除外)?

Objective-c 点表示法或方括号表示法中首选什么?

iPhone 可达性判断

iOS 心率检测算法

有没有办法清除 UIImage 类使用的缓存?

获取对 UIApplication 委托的引用

从 NSString 创建 SHA1 哈希

NSView 的边界与框架

我可以以编程方式滚动到 UIPickerView 中所需的行吗?

Objective-C:如何使用 BOOL 类型的参数调用 performSelector?

iOS - 从应用程序获取 CPU 使用率

使用 DatePicker 展开和折叠 UITableViewCells

添加自定义 initWith?

如何将小时数添加到 NSDate?

NSMutableArray 按顺序添加对象

如何检测 NSString 是否为空?

所有异常断点在模拟器上无缘无故停止

如何调整 UIToolBar 左右内边距

在 Xcode 中制作 RGB colored颜色