OS OC类型和C类型相互转换

OS OC类型和C类型相互转换


__bridge:不涉及对象所有关系改变
__bridge_transfer:给予 ARC 所有权

__bridge_retained:解除 ARC 所有权
形式:
(__bridge type)expression;
(__bridge_retained CF_type)expression;
(__bridge_transfer Objective-C type)expression;

涉及到被转换对象指针和转换对象指针指向的共同内存的释放问题。要小心内存泄露;一般__bridge_retained只用于OC对象到非OC对象的转换;__bridge可以互相转换;__bridge_transfer只能用于非OC对象到OC对象的转换。

在ARC中,OC对象与非OC对象在强制转换中,需要使用以上三个关键字进行桥接,那么三个关键字各用在什么情况下呢?详解如下:
下面一行代码

CFStringRef s1 = (CFStringRef)[[NSString alloc] initWithFormat:@”Hello, %d!”, 1];

在ARC下面会报编译问题,并会给出推荐的解决方案:
CFStringRef s1 = (__bridge CFStringRef)[[NSString alloc] initWithFormat:@”Hello, %d!”, 1];
这里NSString生成的是OC的对象,内存由ARC负责。s1是CF的对象,内存还是需要自己手动管理。两个变量转换时需要添加桥接标识。
上面这种情况下不会crash,也不会有内存泄露。因为alloc出来的内存会被ARC回收,这块内存的所有关系没变。
如果后面加上CFRelease(s1);就会crash,因为这块内存还是归ARC管的,这样会过度释放。

修改一下:
CFStringRef s1 = (__bridge_retained CFStringRef)[[NSString alloc] initWithFormat:@”Hello, %d!”, 1];

这种情况下,对象的所有权交给CF对象了。就需要加上CFRelease(s1);进行释放,否则会产生泄露。

再看下面代码:
CFUUIDRef uu = CFUUIDCreate(NULL);

CFStringRef s2 = CFUUIDCreateString(NULL, uu);
CFRelease(uu);

NSString* str = (__bridge NSString*)s2;
NSLog(@”STR:%@”,str);

CFRelease(s2);
这里的uu和s2都需要使用CFRelease释放,因为他们不是OC对象,并且是create出来的内存,并且所有权没有被释放。

如果改动下面一行代码:
NSString* str = (__bridge_transfer NSString*)s2;

这时候运行程序会引起crash,因为s2的所有权已经交给ARC中的str了,ARC会负责释放这块内存。
这时候调用CFRelease(s2);会造成过度释放。所以应该把这么行代给去了。

注:
ARC模式下,自动回收只针对Objective-C对象有效,对于使用create,copy,retain等生成的Core Foundation对象还是需要我们手动进行释放的,CFRelease().
关于_bridge总结:
(1)OC对象 -> 非OC对象:不涉及对象所有权的转移,即该内存的所有权还是由ARC来处理;
(2)非OC对象 -> OC对象:不涉及对象所有权的转移,即该内存的所有权还是由非OC对象来处理;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值