NSString到CFStringRef和CFStringRef到ARC中的NSString吗? [英] NSString to CFStringRef and CFStringRef to NSString in ARC?

查看:257
本文介绍了NSString到CFStringRef和CFStringRef到ARC中的NSString吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图了解从ARC中的CFStringRef获取NSString的正确方法吗? 反方向也一样,在ARC中从CFStringRefNSString?

在不造成内存泄漏的情况下执行此操作的正确方法是什么?

解决方案

通常

NSString *yourFriendlyNSString = (__bridge NSString *)yourFriendlyCFString;

CFStringRef yourFriendlyCFString = (__bridge CFStringRef)yourFriendlyNSString;

现在,如果您想知道为什么使用__bridge关键字,则可以参考

在这种情况下,您可能希望通过在投射时转移所有权来保存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,这样您将拥有该对象,并且必须使用CFRelease明确释放它. /p>


要包装起来,您可以

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

I am trying to understand the correct way of getting an NSString from a CFStringRef in ARC? Same for going the opposite direction, CFStringRef to NSString in ARC?

What is the correct way to do this without creating memory leaks?

解决方案

Typically

NSString *yourFriendlyNSString = (__bridge NSString *)yourFriendlyCFString;

and

CFStringRef yourFriendlyCFString = (__bridge CFStringRef)yourFriendlyNSString;

Now, if you want to know why the __bridge keyword is there, you can refer to the Apple documentation. There you will find:

__bridge transfers a pointer between Objective-C and Core Foundation with no transfer of ownership.

__bridge_retained or CFBridgingRetain casts an Objective-C pointer to a Core Foundation pointer and 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 and 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 handling the memory of the strings.

There may also be the case in which you want to transfer the ownership for some reason.

For instance consider the following snippet

- (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
}

in such a case you may want to save a CFRelease by transferring the ownership when casting.

- (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 and 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 and you'll have to explicitly release it by using CFRelease.


To wrap it up you can have

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

这篇关于NSString到CFStringRef和CFStringRef到ARC中的NSString吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆